본문 바로가기

Dot Programming/Python

[Python] BeautifulSoup으로 웹 스크래핑하기

    BeautifulSoup으로 웹 스크래핑하기 

    내가 원하는 데이터를 직접 웹 스크래핑하여 보고자한다.

    루비의 최종적인 형태는 받고자하는 정보들을 선택하면 매일 정해진 시간에 카카오톡이나 메일로 보내는 구독형 서비스이다.

     

    그래서 일단 테스트용으로 가볍게 데이터들을 뽑아보려고 한다.

     

    ✔︎ 수집 데이터 (테스트용)

    1. 날씨  -> 네이버 날씨
    2. 영어 회화  -> 해커스
    3. 국내 뉴스 (당일 뉴스 제목, 뉴스 링크) -> 네이버 뉴스
    4. 해외 뉴스 (당일 뉴스 제목, 뉴스 링크) -> CNBC 
    5. 경제 (환율, 대표 주가 지수 변동률)

     

    메인 함수

    if __name__ == "__main__":
        # 현재 시간 출력
        realtime_print()
    
        # 오늘의 날씨 정보 가져오기
        scrap_weather()
    
        # 영어 회화
        scrap_english()
    
        #### 국내 분야별 뉴스 가져오기
        scrap_news("politics")
        scrap_news("economy")
        scrap_news("it")
    
        #### 해외 현재 트렌딩 뉴스
        scrap_global_news("economy")

     

     

    1. 스크래핑 하는 현재 날짜

    ############### 조회 날짜 ###############
    def realtime_print():
        now = datetime.datetime.now()
        nowDate = now.strftime('%Y년 %m월 %d일 (%a)')
        print(f"안녕하세요. 오늘은 {nowDate} 입니다.")  # 2021-05-112
        print()

    출력결과

     

    2. 현재 날씨

    ############## 날씨 ###############
    def scrap_weather():
        weather_url = "https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=%EC%84%9C%EC%9A%B8+%EB%82%A0%EC%94%A8"
        soup = create_soup(weather_url)
    
        weather_data = soup.find("div", attrs={"class": "info_data"})
    
        # 현재 날씨 정보
        weather_info = weather_data.find("p", attrs={
            "class": "cast_txt"
        }).get_text()
    
        # 온도
        pos_degree = weather_data.find("p", attrs={
            "class": "info_temperature"
        }).get_text().replace("도씨", "")
        min_degree = weather_data.find("span", attrs={"class": "min"}).get_text()
        max_degree = weather_data.find("span", attrs={"class": "max"}).get_text()
    
        # 강수 확률
        rainy_data = soup.find("li", attrs={
            "class": "date_info today"
        }).find_all("span", attrs={"class": "num"})
    
        # 미세먼지 정보
        dust_data = soup.find("dl", attrs={
            "class": "indicator"
        }).find_all("dd", attrs={"class": "lv2"})
    
        # 출력
        print("[오늘의 날씨]")
        print(f"현재 {pos_degree} (최저 {min_degree}/ 최고 {max_degree})")
        print(weather_info)
        print(
            f"오전 강수확률 {rainy_data[0].get_text()}% / 오후 강수확률 {rainy_data[1].get_text()}%"
        )
        print(f"미세먼지 {dust_data[0].get_text()}")
        print(f"초미세먼지 {dust_data[1].get_text()}")
        print()
    

    출력결과

     

    3. 영어 회화

    ############### 회화 ###############
    def scrap_english():
        eng_url = "https://www.hackers.co.kr/?c=s_eng/eng_contents/I_others_english&keywd=haceng_submain_lnb_eng_I_others_english&logger_kw=haceng_submain_lnb_eng_I_others_english"
        soup = create_soup(eng_url)
    
        sentences = soup.find_all("div", attrs={"id": re.compile("^conv_kor_t")})
        print("[오늘의 영어 회화]")
        print("(영어지문)")
    
        # 8문장이 있다고 가정, 5~8까지 영어문장 (idx: 4~7)
        for txt in sentences[len(sentences) // 2:]:
            print(txt.get_text().strip())
    
        print()
        print("(한글지문)")
        # 8문장이 있다고 가정, 0~3까지 한글문장 (idx: 0~3)
        for txt in sentences[:len(sentences) // 2:]:
            print(txt.get_text().strip())
        print()
    

    출력결과

     

     

    4. 국내 뉴스

    정치, 경제, IT, 사회, 생활, 세계 분야별로 스크래핑가능하다.

    ############### 국내 News ###############
    # sector
    # politics : 정치
    # economy : 경제
    # it : IT/과학
    # society : 사회
    # life : 생활/문화
    # world : 세계
    def scrap_news(sector):
        news_url = "https://news.naver.com/"
        soup = create_soup(news_url)
    
        # 뉴스 데이터
        news_data = soup.find("div", attrs={"id": f"section_{sector}"})
        # 섹터 이름
        sector_name = news_data.find("h4", attrs={"class": "tit_sec"}).a.get_text()
        # 헤드라인 목록
        news_list = news_data.find("ul", attrs={
            "class": "mlist2 no_bg"
        }).find_all("li")
    
        # 출력
        print(f"[국내 {sector_name} 헤드라인 뉴스]")
        for idx, article in enumerate(news_list):
            headline = article.a.get_text().strip()
            news_link = article.a["href"]
            print(f"{idx+1}. {headline}")
            print(f"   (링크 : {news_link} )")
    
        print()

    출력결과

    5. 해외 뉴스

    ############### 해외 News ###############
    # CNBC Trendig News
    def scrap_global_news(sector):
        news_url = f"https://www.cnbc.com/{sector}/"
        soup = create_soup(news_url)
    
        # 섹터 이름
        sector_name = soup.find("h1", attrs={
            "class": "PageHeader-title"
        }).get_text()
        # 트랜딩 뉴스 데이터
        news_data = soup.find("ul", attrs={"class": "TrendingNow-storyContainer"})
        # 헤드라인 목록
        news_list = news_data.find_all("li")
    
        # 출력
        print(f"[해외 실시간 CNBC 헤드라인 뉴스]")
        for idx, article in enumerate(news_list):
            headline = article.a.get_text().strip()
            news_link = article.a["href"]
            print(f"{idx+1}. {headline}")
            print(f"   (링크 : {news_link} )")
    
        print()

    출력결과