🪧 About  
home
[출판사] 전기장판  
home

[python-크롤링] 파이썬으로 네이버 뉴스 수집하기 - 기사요약 포함

글쓴이
생성일
2019/06/14
카테고리
태그
5 more properties
네이버에서 검색한 뉴스를 긁어오는 코드입니다. 각 홈페이지로 리다이렉트 되는 기사의 경우 주소의 일관성이 없어서 기사 내용은 불러오지 못 합니다. 앞의 "기사내용 포함하여 네이버 뉴스 수집하기"와 다른 점은 기사 내용은 긁어오지 못 하지만, 네이버 뉴스에서 검색해서 나타나는 모든 기사를 각 기사의 요약과 함께 수집합니다.
자세한 설명은 추후 시간이 날 때 하도록 하겠습니다.
아래는 코드 전문입니다.
불필요한 코드들이 중간에 섞여 있습니다.

전체코드

# -*- coding: utf-8 -*- from bs4 import BeautifulSoup from datetime import datetime import requests import pandas as pd import re # 각 크롤링 결과 저장하기 위한 리스트 선언 title_text = [] link_text = [] source_text = [] date_text = [] contents_text = [] result = {} # 엑셀로 저장하기 위한 변수 RESULT_PATH = 'D:/키워드 분석/네이버뉴스(01)/' # 결과 저장할 경로 now = datetime.now() # 파일이름 현 시간으로 저장하기 # %% # 뉴스 수집을 위한 def입니다. # 날짜 정제화 함수 def date_cleansing(test): try: # 지난 뉴스 # 머니투데이 10면1단 2018.11.05. 네이버뉴스 보내기 pattern = '\\\\d+.(\\\\d+).(\\\\d+).' # 정규표현식 r = re.compile(pattern) match = r.search(test).group(0) # 2018.11.05. date_text.append(match) except AttributeError: # 최근 뉴스 # 이데일리 1시간 전 네이버뉴스 보내기 pattern = '\\\\w* (\\\\d\\\\w*)' # 정규표현식 r = re.compile(pattern) match = r.search(test).group(1) # print(match) date_text.append(match) # 내용 정제화 함수 def contents_cleansing(contents): first_cleansing_contents = re.sub('<dl>.*?</a> </div> </dd> <dd>', '', str(contents)).strip() # 앞에 필요없는 부분 제거 second_cleansing_contents = re.sub('<ul class="relation_lst">.*?</dd>', '', first_cleansing_contents).strip() # 뒤에 필요없는 부분 제거 (새끼 기사) third_cleansing_contents = re.sub('<.+?>', '', second_cleansing_contents).strip() contents_text.append(third_cleansing_contents) # print(contents_text) def crawler(maxpage, query, sort, s_date, e_date): s_from = s_date.replace(".","") e_to = e_date.replace(".","") page = 1 maxpage_t = (int(maxpage) - 1) * 10 + 1 # 11= 2페이지 21=3페이지 31=4페이지 ...81=9페이지 , 91=10페이지, 101=11페이지 while page <= maxpage_t: url = "<https://search.naver.com/search.naver?where=news&query=>" + query + "&sort=" + sort + "&ds=" + s_date + "&de=" + e_date + "&nso=so%3Ar%2Cp%3Afrom" + s_from + "to" + e_to + "%2Ca%3A&start=" + str(page) response = requests.get(url) html = response.text # 뷰티풀소프의 인자값 지정 soup = BeautifulSoup(html, 'html.parser') # <a>태그에서 제목과 링크주소 추출 atags = soup.select('._sp_each_title') for atag in atags: title_text.append(atag.text) # 제목 link_text.append(atag['href']) # 링크주소 # 신문사 추출 source_lists = soup.select('._sp_each_source') for source_list in source_lists: source_text.append(source_list.text) # 신문사 # 날짜 추출 date_lists = soup.select('.txt_inline') for date_list in date_lists: test = date_list.text date_cleansing(test) # 날짜 정제 함수사용 # 본문요약본 contents_lists = soup.select('ul.type01 dl') for contents_list in contents_lists: # print('==='*40) # print(contents_list) contents_cleansing(contents_list) # 본문요약 정제화 # 모든 리스트 딕셔너리형태로 저장 result = {"date": date_text, "title": title_text, "source": source_text, "contents": contents_text, "link": link_text} print(page) df = pd.DataFrame(result) # df로 변환 page += 10 # 새로 만들 파일이름 지정 outputFileName = '%s-%s-%s %s시 %s분 %s초 merging.xlsx' % (now.year, now.month, now.day, now.hour, now.minute, now.second) df.to_excel(RESULT_PATH + outputFileName, sheet_name='sheet1') def crawler_csv(maxpage, query, sort, s_date, e_date): # 엑셀이 아닌 csv로 작성하기 s_from = s_date.replace(".", "") e_to = e_date.replace(".", "") page = 1 maxpage_t = (int(maxpage) - 1) * 10 + 1 # 11 = 2페이지 21 = 3페이지 31 = 4페이지...81 = 9페이지, 91 = 10페이지, 101 = 11페이지 while page <= maxpage_t: url = "<https://search.naver.com/search.naver?where=news&query=>" + query + "&sort="+sort+"&ds=" + s_date + "&de=" + e_date + "&nso=so%3Ar%2Cp%3Afrom" + s_from + "to" + e_to + "%2Ca%3A&start=" + str(page) response = requests.get(url) html = response.text # 뷰티풀소프의 인자값 지정 soup = BeautifulSoup(html, 'html.parser') # <a>태그에서 제목과 링크주소 추출 atags = soup.select('._sp_each_title') for atag in atags: title_text.append(atag.text) # 제목 link_text.append(atag['href']) # 링크주소 # 신문사 추출 source_lists = soup.select('._sp_each_source') for source_list in source_lists: source_text.append(source_list.text) # 신문사 # 날짜 추출 date_lists = soup.select('.txt_inline') for date_list in date_lists: test = date_list.text date_cleansing(test) # 날짜 정제 함수사용 # 본문요약본 contents_lists = soup.select('ul.type01 dl') for contents_list in contents_lists: # print('==='*40) # print(contents_list) contents_cleansing(contents_list) # 본문요약 정제화 # 모든 리스트 딕셔너리형태로 저장 result = {"date": date_text, "title": title_text, "source": source_text, "contents": contents_text, "link": link_text} print(page) df = pd.DataFrame(result) # df로 변환 page += 10 # 새로 만들 파일이름 지정 outputFileName = '%s-%s-%s %s시 %s분 %s초 merging.csv' % (now.year, now.month, now.day, now.hour, now.minute, now.second) df.to_csv(RESULT_PATH + outputFileName, mode='a', sep="") def main_mod(): x = 0 # 연도별로 반복시키기 위해서(400줄 이상 네이버가 검색 결과를 제공하지 않기 때문에, 400줄 단위로 작업해야 하며, 연도를 나눠야 한다.) while x < 20: maxpage = 400 query = '"문화영향평가"' sort = "0" s_date = "20{0:0>2}.01.01".format(x) # 2019.01.01 e_date = "20{0:0>2}.12.31".format(x) # 2019.04.28 crawler_csv(maxpage, query, sort, s_date, e_date) x += 1 # %% main_mod() # %% # 경우에 따라 마지막 뉴스가 수백번 중복되는 경우가 발생하여 중복 제거가 필요 import csv my_columns = [1, 2, 3, 4, 5] with open('D:/키워드 분석/네이버뉴스(01)/contents.csv', 'r', encoding='utf-8') as f: with open('D:/키워드 분석/네이버뉴스(01)/contents_mod.txt', 'w', encoding='utf-8') as nf: filereader = csv.reader(f) filewriter = csv.writer(nf) # 헤더를 안 지우는 이유는 이미 여러번 들어가 있다. for row_list in filereader: row_list_output = [] for index_value in my_columns: row_list_output.append(row_list[index_value]) filewriter.writerow(row_list_output) with open('D:/키워드 분석/네이버뉴스(01)/contents_mod.txt', 'r', encoding='utf-8') as f: list_file = f.readlines() list_file = [line.rstrip('\\\\n') for line in list_file] new_list = list(set(list_file)) # 중복 뉴스기사 제거하기 with open('D:/키워드 분석/네이버뉴스(01)/contents_mod.txt', 'w', encoding='utf-8') as nf: for line in new_list: nf.write(line + '\\\\n') # 헤더(date,title,source,contents,link)가 여러번 들어가 있으나, 중복 제거에서 한 번만 남는다. 위치는 어디인지 알 수 없다. # 날짜가 아닌, 1일 7일 5시간 형태로 나타나는 경우가 존재하며, 이 경우 데이터 오류가 아닌, 수집 시점에서 일주일이 지나지 않을 경우 네이버가 날짜를 표시하지 않아 생기는 문제.
Plain Text
Copyright ⓒ 2022 SADAM Media All Rights Reserved.
사담미디어(SADAM Media) / 사업자번호: 703-37-00838