네이버에서 검색한 뉴스를 긁어오는 코드입니다. 각 홈페이지로 리다이렉트 되는 기사의 경우 주소의 일관성이 없어서 기사 내용은 불러오지 못 합니다. 앞의 “기사내용 포함하여 네이버 뉴스 수집하기”와 다른 점은 기사 내용은 긁어오지 못 하지만, 네이버 뉴스에서 검색해서 나타나는 모든 기사를 각 기사의 요약과 함께 수집합니다.
자세한 설명은 추후 시간이 날 때 하도록 하겠습니다.
아래는 코드 전문입니다.
불필요한 코드들이 중간에 섞여 있습니다.
전체코드
# -*- 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)
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)
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 = f"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:
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 = f"{now.year}-{now.month}-{now.day} {now.hour}시 {now.minute}분 {now.second}초 merging.xlsx"
df.to_excel(RESULT_PATH + outputFileName, sheet_name='sheet1')
def crawler_csv(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 = f"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:
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 = f"{now.year}-{now.month}-{now.day} {now.hour}시 {now.minute}분 {now.second}초 merging.csv"
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 = f"20{x:0>2}.01.01" # 2019.01.01
e_date = f"20{x:0>2}.12.31" # 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시간 형태로 나타나는 경우가 존재하며, 이 경우 데이터 오류가 아닌, 수집 시점에서 일주일이 지나지 않을 경우 네이버가 날짜를 표시하지 않아 생기는 문제.
Code language: Python (python)
댓글 남기기