기사 검색하기
아래와 같이 네이버 뉴스 검색 부분에 '사건 + 사고'를 검색하면,
전체 URL은 "https://search.naver.com/search.naver?where=news&query=[검색키워드]&sm=tab_opt&sort=1&photo=0&field=0&pd=1&ds=2024.09.13&de=2024.09.20&docid=&related=0&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so%3Add%2Cp%3A1w&is_sug_officeid=0&office_category=0&service_area=0" 형태임을 알 수 있다.
① https://search.naver.com/search.naver?where=news&query=[검색키워드] 이부분은 변하지 않는 부분이고,
②"&sm=tab_opt&sort=1&photo=0&field=0&pd=1&ds=2024.09.13&de=2024.09.20&docid=&related=0&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so%3Add%2Cp%3A1w&is_sug_officeid=0&office_category=0&service_area=0" 이부분은 오션에 따라 달라짐을 알 수 있다.
bs 라이브러리를 사용하여 뉴스 검색 URL에서 뉴스 제목, 언론사, 게시일, 요악을 크롤링 하는 코드는 아래와 같고,
resp = requests.get( [URL(키워드 포함)], headers=headers, verify=False)
soup = bs(resp.text, 'html.parser')
#print(resp.text)
news_title = soup.findAll("a", {"class":"news_tit"})
news_info = soup.findAll("a", {"class":"info press"})
news_date = soup.findAll("span", {"class":"info"})
news_contents = soup.findAll("a", {"class":"api_txt_lines dsc_txt_wrap"})
위 코드를 포함한 뉴스를 검색하는 코드는 아래와 같다.
# -*- coding: utf-8 -*-
import requests
import urllib.parse
import warnings
import time
import os.path
from datetime import datetime
from bs4 import BeautifulSoup as bs
warnings.filterwarnings("ignore")
#--------------------------
# 메인
#--------------------------
def main():
keywords = [
'사건 + 사고',
'독점 + 수사'
]
# csv 헤더
header_list = ['No','Title','Media','URL','description','pubDate','UID','KeyWord']
# 뉴스 검색 URL 1 (고정)
prefix_url = "https://search.naver.com/search.naver?where=news&query="
# 뉴스 검색 URL 2 (옵션)
suffix_url = "&sm=tab_srt&sort=1&photo=0&field=0&reporter_article=&pd=12&ds=2024.09.15.07.06&de=2024.09.20.13.06&docid=&nso=so%3Add%2Cp%3Aall%2Ca%3Aall&mynews=0&refresh_start=0&related=0"
# User-Agent
headers = { 'user-agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' }
time.sleep(5)
cnt=0
# 60초 간격으로 반복
while True:
print("[검색]" + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
# 키워드 여러개 사용
for keyword in keywords:
# 전체 URL
resp = requests.get(prefix_url + urllib.parse.quote(keyword) + suffix_url, headers=headers, verify=False)
resp.encoding = None
# bs 을 사용한 html 파싱하기
soup = bs(resp.text, 'html.parser')
#print(resp.text)
# 파싱 결과물에서 제목, 정보, 게시일, 요약 찾아 저장하기
news_title = soup.findAll("a", {"class":"news_tit"})
news_info = soup.findAll("a", {"class":"info press"})
news_date = soup.findAll("span", {"class":"info"})
news_contents = soup.findAll("a", {"class":"api_txt_lines dsc_txt_wrap"})
# 기사별로 구분하기
for i in range(len(news_title)):
title = news_title[i].get('title')
link = news_title[i].get('href')
description = "'{0}'".format(news_contents[i].get_text())
pubDate = news_date[i].get_text()
author = news_info[i].get_text()
# 출력
print(pubDate)
print(author)
print(title)
print(link)
print(description)
print("[대기]" + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
# 60초 딜레이
time.sleep(60)
#--------------------------
# Main
#--------------------------
if __name__ == "__main__":
main()
검색된 기사는 패스하기
1분마다 기사를 검색하기에 '제목'과 '뉴스 URL'을 합치 문자열을 SHA1 해시로 변환해서 UID를 생성하여 기록한 후, 동일 UID에 대해서는 패스하도록 코드를 넣으면 한 번 검색된 기사는 다시 출력하지 않을 수 있습니다.
#--------------------------
# 기사 UID 생성
#--------------------------
def UID_make(str):
result = hashlib.sha1(str.encode())
enVal = result.hexdigest()
return enVal
#--------------------------
# 기사 UID 체크
#--------------------------
def Check_UID(file, uid):
enVal = False
if os.path.isfile(file):
with open(file,encoding='utf-8',newline='') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
if uid == row['UID']:
enVal = True
break
return enVal
#--------------------------
# 메인
#--------------------------
def main():
기사 검색...
# check UID
title_media = "{0} - {1}".format(title,link)
uid = UID_make(title_media)
if Check_UID(file, uid):
break
else:
print('기사출력')
#--------------------------
# Main
#--------------------------
if __name__ == "__main__":
main()
검색된 기사 저장하기
네이버 뉴스를 검색하기 csv 파일로 저장하는 코드는 아래와 같다.
# 파일의 첫 번째 행은 헤더 추가
if cnt == 0:
cnt = cnt+1
else:
with open(file,encoding='utf-8',newline='') as csvfile:
reader = csv.DictReader(csvfile)
cnt = 1
for row in reader:
cnt=cnt+1
# 뉴스 기사 출력
print(" ------------------------------------------------------------ ")
print("{0}. {1}".format(cnt, title_media))
print('URL:{0}'.format(link))
print(description)
print(" ------------------------------------------------------------ ")
# 파일 오픈
f = open(file,'a',encoding='utf-8',newline='')
csvWriter = csv.writer(f)
if cnt==1:
csvWriter.writerow(header_list)
# 파일 저장
csvWriter.writerow([cnt,title,author,link,description, pubDate,uid,keyword])
msg = "▶ {0}({1})\n{2}\n{3}".format(title, pubDate, description, link)
print(msg)
#파일 닫기
f.close()
전체 코드
위 네이버 뉴스 검색, UID 생성/체크, CSV파일로 저장하는 소스를 합친 전체적인 코드는 아래와 같다.
# -*- coding: utf-8 -*-
import requests
import urllib.parse
import warnings
import time
import csv
import os.path
from datetime import datetime
import hashlib
from bs4 import BeautifulSoup as bs
warnings.filterwarnings("ignore")
#--------------------------
# Main
#--------------------------
def TimeConvert(strTime):
inputTimeFormat = "%a, %d %b %Y %H:%M:%S %z"
outputTimeFormat = "%Y-%m-%d %H:%M:%S"
objTime = datetime.strptime(strTime, inputTimeFormat)
enVal = objTime.strftime(outputTimeFormat)
return enVal
#--------------------------
# 기사 UID 생성
#--------------------------
def UID_make(str):
result = hashlib.sha1(str.encode())
enVal = result.hexdigest()
return enVal
#--------------------------
# 기사 UID 체크
#--------------------------
def Check_UID(file, uid):
enVal = False
if os.path.isfile(file):
with open(file,encoding='utf-8',newline='') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
if uid == row['UID']:
enVal = True
break
return enVal
#--------------------------
# 메인
#--------------------------
def main():
keywords = [
'사건 + 사고',
'독점 + 수사'
]
# csv 헤더
header_list = ['No','Title','Media','URL','description','pubDate','UID','KeyWord']
# 뉴스 검색 URL 1 (고정)
prefix_url = "https://search.naver.com/search.naver?where=news&query="
# 뉴스 검색 URL 2 (옵션)
suffix_url = "&sm=tab_srt&sort=1&photo=0&field=0&reporter_article=&pd=12&ds=2024.09.15.07.06&de=2024.09.20.13.06&docid=&nso=so%3Add%2Cp%3Aall%2Ca%3Aall&mynews=0&refresh_start=0&related=0"
# User-Agent
headers = { 'user-agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' }
print("____________________________________________")
print(" 네이버 뉴스 검색 ")
print("____________________________________________")
time.sleep(5)
file = f'C:/Work/navernews_{datetime.today().strftime("%Y%m%d")}.csv'
cnt=0
# 60초마다 반복
while True:
print("[검색]" + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
# 검색어 별로 크롤링
for keyword in keywords:
# 전체 URL
resp = requests.get(prefix_url + urllib.parse.quote(keyword) + suffix_url, headers=headers, verify=False)
resp.encoding = None
# URL 파싱
soup = bs(resp.text, 'html.parser')
#print(resp.text)
# 기사제목, 언론사, 게시일, 요약 내용만 크롤링
news_title = soup.findAll("a", {"class":"news_tit"})
news_info = soup.findAll("a", {"class":"info press"})
news_date = soup.findAll("span", {"class":"info"})
news_contents = soup.findAll("a", {"class":"api_txt_lines dsc_txt_wrap"})
for i in range(len(news_title)):
title = news_title[i].get('title')
link = news_title[i].get('href')
description = "'{0}'".format(news_contents[i].get_text())
pubDate = news_date[i].get_text()
author = news_info[i].get_text()
#print(pubDate)
#print(author)
#print(title)
#print(link)
#print(description)
# UID 생성하기
title_media = "{0} - {1}".format(title,link)
uid = UID_make(title_media)
# UID 확인하기
if Check_UID(file, uid):
break
else:
if cnt == 0:
cnt = cnt+1
else:
# CSV 파일 열기
with open(file,encoding='utf-8',newline='') as csvfile:
reader = csv.DictReader(csvfile)
cnt = 1
for row in reader:
cnt=cnt+1
print(" ------------------------------------------------------------ ")
print("{0}. {1}".format(cnt, title_media))
print('URL:{0}'.format(link))
print(description)
print(" ------------------------------------------------------------ ")
f = open(file,'a',encoding='utf-8',newline='')
csvWriter = csv.writer(f)
# CSV 파일 해더 추가하기
if cnt==1:
csvWriter.writerow(header_list)
# CSV 저장하기
csvWriter.writerow([cnt,title,author,link,description, pubDate,uid,keyword])
msg = "▶ {0}({1})\n{2}\n{3}".format(title, pubDate, description, link)
print(msg)
f.close()
print("[대기]" + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
# 60초 대기
time.sleep(60)
#--------------------------
# Main
#--------------------------
if __name__ == "__main__":
main()
네이버뉴스 크롤링 실행 결과
'공학속으로 > python' 카테고리의 다른 글
[python] csv 파일을 excel 파일로 변환하기 (0) | 2023.08.17 |
---|---|
[python] 텍스트 파일에서 IP을 추출하여 저장하기 (0) | 2023.08.11 |
[Python] 구글 크롤링하기 (0) | 2023.08.08 |
[Python] 압축 파일 비밀번호 풀기 (0) | 2023.07.20 |
[Python] ChatGPT API 사용하기 (0) | 2023.07.06 |
댓글