Code/파이썬

[Python] Selenium 을 이용한 뉴스 크롤링 해오기 (feat. Beutiful Soup)

마메프 2021. 10. 22. 11:47
반응형

오늘은 Beutiful Soup 과 Selenium 을 통해

뉴스 헤드라인, url > 작성 날짜, 작성 기자, 뉴스 기사 를 크롤링 해 볼 것이다.

 

+) 뉴스 기사는 기자 및 출판사에 저작물 등록이 되어있으므로 상업적 용도로 사용 불가능하다. 또한 크롤링도 해당 사이트의 robots.txt 가 허용되는지 확인 후 크롤링 하도록 하자.

 

 

먼저 Selenium 을 추가적으로 사용하는 이유는 뉴스 페이지들의 동작 방식 때문인데, 반응형 웹페이지 같은 동적 페이지에서는 Beutiful soup의 selector 가 제 기능을 못하기 때문이다.


첫번째로, 환경 세팅을 해보자! 사용할 라이브러리, ChromeDriver들을 다운 받아준다.

pip install bs4
pip install selenium

.

(중요! 꼭 자신의 컴퓨터에 설치된 크롬 버전과 같은지 확인하여야함.)

sites.google.com/chromium.org/driver/

 

ChromeDriver - WebDriver for Chrome

WebDriver is an open source tool for automated testing of webapps across many browsers. It provides capabilities for navigating to web pages, user input, JavaScript execution, and more. ChromeDriver is a standalone server that implements the W3C WebDriver

sites.google.com

 

각자 환경에 맞는 알집파일을 설치 후, 안에 들어있는 .exe 파일경로를 메모해두거나, Path 경로로 지정해준다.

나는윈도우 환경이기 때문에, chromedriver_win32.zip을 풀어서,  C:/chrome/ 경로에 넣어두었다.


자 이제 모든 준비가 끝이다. 다시 정리하자면 내가 크롤링하여 저장하길 원하는 값들은 다음과 같다.

  1. 뉴스 헤드라인
  2. 뉴스 출판사
  3. 뉴스 url
  4. 작성 날짜
  5. 작성 기자
  6. 뉴스 기사

뉴스 헤드라인과 뉴스 url은 구글 뉴스 (seed url)를 통해 얻을것이며, 나머지들은(4-6) 값에 따라 얻어진 url경로를 타고 가져올 수 있을 것 같다. 

 

soup의 셀렉터를 카피해 오는 방법은 F12 를 눌러 개발자도구를 연 다음, Elements에서 해당 텍스트가 들어있는 블록을 찾아주면된다. 그 후에는 손쉽게 우클릭으로 selector를 카피해서 사용하면된다! (우클릭 > Copy > Copy selector)

 

 

먼저, 구글 뉴스에서 1,2,3번 항목을 가져오는 코드는 다음과 같다. 

from bs4 import BeautifulSoup
url = 'https://news.google.com/topics/CAAqIQgKIhtDQkFTRGdvSUwyMHZNRFp4WkRNU0FtdHZLQUFQAQ?hl=ko&gl=KR&ceid=KR%3Ako'
def get_news_heads():
    resp = requests.get(url)
    soup = BeautifulSoup(resp.text, 'lxml')
    items = soup.select('div > article > h3 > a')
    for idx, item in enumerate(items): # nth-child 는 nth-of-type 으로 바꾸어줘야 한다.
        publisher = soup.select('main > div.lBwEZb.BL5WZb.GndZbb '
                                '> div:nth-of-type({0}) > div > div > article '
                                '> div > div > a'.format(idx+1)) # 해당 idx 출판사 이름을 가져옴
        if len(publisher) == 0: continue # 없을 경우 continue
        
        pub = publisher[0].getText() #뉴스 출판사
        title = item.text #뉴스 헤드라인
        link = 'https://news.google.com'+str(item.get('href')) #뉴스 경로
        
        print('---------------------------------')
        print('IDX : ', idx, pub, title , link)

 

다음으로는 Selenium을 사용해 접근할 것이다. 보통의 뉴스 출판사 홈페이지는 Soup을 통한 접근이 충분히 가능하지만, 조선일보의 경우 반응형 웹페이지였기 때문에, 크롤링하게되면 원하는 결과값이 아닌 Javascript가 나온다.

이를 selenium으로 가져와 보자! 코드는 다음과 같다. 

Xpath 가져오는 방법은 저번글 하단 < 에도 기술되어있다. selector 와 똑같이 해주면 된다.

from selenium import webdriver
from datetime import datetime

def get_news_info(n_url, publisher): # n_url = 뉴스 url , publisher = 뉴스 출판사
    date, article, writer = None,'', ''
    if publisher == '조선일보': # 동적 페이지.
        driver = webdriver.Chrome('C:/chrome/chromedriver.exe')
        driver.implicitly_wait(3)
        ## url에 접근한다.
        driver.get(n_url)
        
        # 뉴스 작성자
        writer = driver.find_element_by_xpath(
        	'//*[@id="fusion-app"]/div[1]/div[2]/div/section/article/div[1]/div/a'
            ).text.split()[0]
        
        # 작성 날짜
        # 입력 2021.10.16 14:48 
        date_time_obj = driver.find_element_by_xpath(
        	'//*[@id="fusion-app"]/div[1]/div[2]/div/section/article/div[2]/span'
            ).text[3:]
        date = datetime.strptime(date_time_obj, '%Y.%m.%d %H:%M') # 날짜포맷.
        
        # 기사블록 순회하며 모든 text 저장
        i = 1
        while True:
            try:
                article += driver.find_element_by_xpath(
                    '//*[@id="fusion-app"]/div[1]/div[2]/div'
                    '/section/article/section/p[{0}]'.format(i)
                    ).text
                i+=1
            except:
                break
        # 드라이버 종료 
        driver.quit()
    print('================================================')
    print(publisher,' , 작성자 : ', writer)
    print(' 날짜 :', date)
    print(' 기사 :', article)
    print('================================================')
    return writer, article, date

 

이로써 원하는 뉴스 기사 요소들을 가져오는 크롤링 코드들이 완성되었다.

다시한번 언급하지만, 뉴스 기사와 기자는 저작물로 등록되어있기 때문에 별도의 상업적인 용도로 사용은 불가능하다.

 

아무튼 잘되어서 굳굳!

반응형