DevKim

[Requests & BeautifulSoup] 네이버 뉴스 기사 크롤링하기 본문

데이터 수집 [ Web crawling ]

[Requests & BeautifulSoup] 네이버 뉴스 기사 크롤링하기

on_doing 2021. 1. 16. 21:41
728x90

밑에 코드를 정상적으로 실행하기 위해, 별도의 data 폴더와 base path가 설정되어있어야한다.

사실상 네이버 뉴스의 모든 뉴스를 크롤링하기엔 불가능하다.

왜냐하면 네이버 뉴스를 클릭해보면 알겠지만, 연합뉴스,한국뉴스...등등

모두 다른 회사에서 만든 뉴스기사임을 볼 수 있다.

그렇다고 모~~든 회사에서 만든 다른 web 의 태깅들을 따로따로 입력할 수도 없는 노릇이다.

 

그래서 해결방안은 naver 뉴스에 연결되어있는 애들만 크롤링하는 방법이다. 

 

검색어와, 뉴스가 발행된 날짜, 크롤링 할 페이지를 입력하면 자동으로 엑셀파일에 저장되게끔 코드가 짜여져있다

# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
import pandas as pd
from datetime import datetime
from pprint import pprint
from tqdm import tqdm_notebook 

RESULT_PATH = base_path + '/data/'
now = datetime.now() #파일이름 현 시간으로 저장하기

def get_news(n_url):
    news_detail = []

    breq = requests.get(n_url, headers={'User-Agent':'Mozilla/5.0'}) 
    bsoup = BeautifulSoup(breq.content, 'lxml') 
    

    #뉴스 제목
    title = bsoup.select('h3#articleTitle')[0].text  
    news_detail.append(title)
      

    #날짜
    pdate = bsoup.select('.t11')[0].get_text()[:11]
    news_detail.append(pdate)


    _text = bsoup.select('#articleBodyContents')[0].get_text().replace('\n', " ")
    _text = _text.replace("    동영상 뉴스   ", "")
    btext = _text.replace("// flash 오류를 우회하기 위한 함수 추가 function _flash_removeCallback() {}", "")
    news_detail.append(btext.strip())

    #링크주소
    news_detail.append(n_url)
    
    #기사출처기업
    pcompany = bsoup.select('#footer address')[0].a.get_text()
    news_detail.append(pcompany)

    return news_detail 


def crawler(maxpage,query,s_date,e_date):

    crawled_data = {}
    years = []
    company = []
    title = []
    contents = []
    link = []
    s_from = s_date.replace(".","")
    e_to = e_date.replace(".","")
    page = 1
    maxpage_t =(int(maxpage)-1)*10+1 
    f = open(base_path + f"/data/contents_text_{query}.txt", 'w', encoding='utf-8-sig')

    
    for page in tqdm_notebook(range(1, maxpage_t+1, 10)):

        url="https://search.naver.com/search.naver?&where=news&query="+query+"&sort=0&photo=0&field=0&reporter_article=&pd=3&ds="+s_date+"&de="+e_date+"&docid=&nso=so:r,p:from"+s_from+"to"+e_to+",a:all&mynews=0&cluster_rank=26&start="+str(page)
        
        req = requests.get(url,
                          headers={'User-Agent':'Mozilla/5.0'})
        print(url)
        cont = req.content
        soup = BeautifulSoup(cont, 'lxml')
        
        for urls in soup.find_all("a", class_="info"):
            try :
                if urls.get_text() == "네이버뉴스": 
                    print(urls["href"])
                    news_detail = get_news(urls["href"]) 
                        # pdate, pcompany, title, btext
                    f.write("{}\t{}\t{}\t{}\t{}\n".format(news_detail[1], news_detail[4], news_detail[0], news_detail[2],news_detail[3]))  # new style
                    years.append(news_detail[1])
                    company.append(news_detail[4])
                    title.append(news_detail[0])
                    contents.append(news_detail[2])
                    link.append(news_detail[3])
                    
            except Exception as e:
                print(e)
                continue
        
    crawled_data["years"] = years
    crawled_data["company"] = company
    crawled_data["title"] = title
    crawled_data["contents"] = contents
    crawled_data["link"] = link
    f.close()
    return crawled_data
    
def excel_make(crawled_data):
    data = pd.DataFrame(crawled_data)
    
    xlsx_outputFileName = f'{query}_({s_date}~{e_date}).xlsx'
    data.to_excel(RESULT_PATH+xlsx_outputFileName, encoding='utf-8-sig')


maxpage = input("최대 출력할 페이지수 입력하시오: ")
if not maxpage.isdigit():
    maxpage = input("최대 출력할 페이지수 입력하시오: ")
query = input("검색어 입력: ")
s_date = input("시작날짜 입력(ex) 2020.01.01):")  
e_date = input("끝날짜 입력(ex) 2020.12.31):")
crawled_data = crawler(maxpage,query,s_date,e_date) 
excel_make(crawled_data)
728x90
Comments