안녕하세요?
오늘은 저번시간에 했던 파이썬을 이용한 네이버 뉴스 스크래핑에 좀 더 심화한 내용을 가져왔습니다.
저번시간까지는 네이버에 '인공지능'을 검색했을 때 나오는 첫페이지에만 해당되는 기사들을 하나 하나씩 스크래핑을 했다면,
오늘은 첫번째 페이지만이 아니라 내가 원하는 페이지까지 넘어가서, 내가 원하는 날짜 안에 작성된 기사들을, 내가 원하는 정렬타입에 맞게 순서대로 스크래핑을 해보려고 합니다.
저번시간 내용까지 이해를 잘 하셨다면 어려운 부분이 전혀 없습니다.
코드의 굵은 뼈대는 저번시간과 동일합니다.
거기에 제가 원하는 페이지나, 날짜나, 정렬타입을 설정하려면 그저 해당 url이 어떤 규칙성을 가지고 바뀌는지만 파악해서 적용해주면 끝납니다.
먼저 네이버에 인공지능을 검색한 후 정렬 기준은 최신순, 기간은 23년 1월 1일 ~ 2월 1일로 설정하고 페이지는 2페이지로 넘어갔을 때 url이 어떻게 바뀌는지 한번 확인해 보겠습니다. (실제로는 다양한 설정을 왔다갔다 해보며 확인해야 규칙성이 보일 것입니다.)
https://search.naver.com/search.naver?
where=news&
sm=tab_pge&
query=인공지능&
sort=1& #★ sort : 정렬 -> 0:관련도순, 1:최신순, 2:오래된순
photo=0&
field=0&
pd=0&
ds=2023.01.01& #★ 2023년 1월 1일 부터 ~
de=2023.02.01& #★ 2023년 2월 1일 까지 !!
cluster_rank=71&
mynews=0&
office_type=0&
office_section_code=0&
news_office_checked=&
nso=so%3Ar%2Cp%3Afrom20230101to20230201 #★ 그런데 날짜 진짜 바뀌는 부분은 여기!!!
start=11 #★ 11번째 기사글부터 보여달라~~~
실제로 url이 어떤 규칙성을 바뀌는지 검색해보면 sort와, ds de, 그리고 nso와 start 부분이 바뀌는 것을 볼 수 있습니다.
이때 날짜가 바뀌는 부분이 ds de 그리고 nso의 from ~~ to ~~ 부분이 있는데 실제로 코드에 영향을 미치는 부분은 nso 부분이기 때문에 코드에 nso부분을 고쳐주셔야 합니다. (ds와 de는 nso를 바꾸면 자동으로 바뀌는 부분)
(+ 한페이지당 글이 10개씩 있기 때문에 2페이지 첫 글은 11번째 글이 되는 것입니다.)
(+ 다른 부분들은 크게 바뀌는 부분이 없기때문에 저번시간처럼 코드에 url을 넣을때 빼고 넣으셔도 됩니다.)
무작정 페이지를 넘겨서 계속 스크래핑을 하다보면 코드가 무한히 실행될 것이기 때문에, 실제로 코드를 작성할 때는 어느 페이지까지 스크래핑을 할 것인지 원하는 값을 입력해주고 while문을 통해 원하는 페이지에 도착할때 까지만 스크래핑을 반복해주는 식으로 설정을 하면 됩니다.
(+ 첫 페이지가 끝나고 start값이 +10이 되게끔 설정)
(+ 추가로 대량의 데이터를 대상으로 스크래핑을 할 때에는 요청 사이에 쉬어주는 타이밍을 넣어주는 것이 좋습니다. 빠르게 돌리면 디도스같은 바이러스 공격으로 인식해서 ip를 막아버릴 수 있으니 time라이브러리의 sleep함수를 넣어주어 페이지 중간 중간에 코드를 쉬게끔 해주는 것이 좋습니다.)
한가지 더 팁을 드리자면, 예를들어 '인공지능' 이라는 문구가 반드시 포함된 문서만을 검색하려면
query = '"인공지능"'
# or
query = "\"인공지능\""
query를 만들 때 작은따옴표 안에 큰따옴표를 넣어주어 만들어주거나, 큰따옴표 안에 문자로 만들어주고 싶은 문구의 큰따옴표 사이에 카운터슬래시를 넣어주면 됩니다.
실제로 네이버에 이런식으로 검색을 하게 되면 그 검색어가 반드시 포함된 것만 나오게 됩니다.
이제 코드를 깔끔히 정리하여 작성해보도록 하겠습니다.
스크래핑을 하는 부분을 하나의 함수로 정의하여 -> 내가 원하는 설정값들을 입력만해주면 -> 언제든 불러와 꺼내쓸 수 있게끔 만들어보았습니다.
def main_crawling(query, start_date, end_date, sort_type, max_page):
# 유저가 이상한 값을 넣어줬으면 ... -> 디폴트값 설정
if query == '':
query = '인공지능'
if len(start_date) != 10:
start_date = '2022.01.01'
if len(end_date) != 10:
end_date = '2022.12.31'
if sort_type not in ['0', '1', '2']:
sort_type = '0'
# if max_page == '':
# max_page = 5
# 각 기사들의 데이터를 종류별로 나눠담을 리스트를 생성합니다. (추후 DataFrame으로 모을 예정)
titles = []
dates = []
articles = []
article_urls = []
press_companies = []
# 주어진 일자를 쿼리에 맞는 형태로 변경해줍니다.
start_date = start_date.replace(".", "")
end_date = end_date.replace(".", "")
# 지정한 기간 내 원하는 페이지 수만큼의 기사를 크롤링합니다.
current_call = 1
last_call = (max_page - 1) * 10 + 1 # max_page이 5일 경우 41에 해당
while current_call <= last_call:
print('\n{}번째 기사글부터 크롤링을 시작합니다.'.format(current_call))
url = "https://search.naver.com/search.naver?where=news&query=" + query \
+ "&sort=" + sort_type \
+ "&nso=so%3Ar%2Cp%3Afrom" + start_date \
+ "to" + end_date \
+ "%2Ca%3A&start=" + str(current_call)
urls_list = []
try: # 네이버 뉴스 검색결과 페이지 자체에 접근이 불가능할 경우 에러가 발생할 수 있습니다.
web = requests.get(url).content
source = BeautifulSoup(web, 'html.parser')
for urls in source.find_all('a', {'class' : "info"}):
if urls["href"].startswith("https://n.news.naver.com"):
urls_list.append(urls["href"])
except:
print('해당 뉴스 검색 페이지의 네이버 뉴스 링크를 모으는 중 에러가 발생했습니다. : ', url)
# urls_list : 해당 페이지에 있는 "네이버 뉴스"의 링크 모음(list)
if urls_list != []:
for url in urls_list:
try: # 특정 뉴스 기사글 하나를 크롤링하는 중 에러가 발생할 수 있습니다.
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
web_news = requests.get(url, headers=headers).content
source_news = BeautifulSoup(web_news, 'html.parser')
title = source_news.find('h2', {'class' : 'media_end_head_headline'}).get_text()
print('Processing article : {}'.format(title))
date = source_news.find('span', {'class' : 'media_end_head_info_datestamp_time'}).get_text()
article = source_news.find('div', {'id' : 'dic_area'}).get_text()
article = article.replace("\n", "")
article = article.replace("// flash 오류를 우회하기 위한 함수 추가function _flash_removeCallback() {}", "")
article = article.replace("동영상 뉴스 ", "")
article = article.replace("동영상 뉴스", "")
article = article.strip()
press_company = source_news.find('em', {'class':'media_end_linked_more_point'}).get_text()
titles.append(title)
dates.append(date)
articles.append(article)
press_companies.append(press_company)
article_urls.append(url)
except:
print('\n*** {}번부터 {}번까지의 기사글을 크롤링하는 중 문제가 발생했습니다.'.format(current_call, current_call+9))
print('*** 다음 링크의 뉴스를 크롤링하는 중 에러가 발생했습니다 : {}'.format(url))
else:
pass
time.sleep(5)
current_call += 10
article_df = pd.DataFrame({'Title':titles,
'Date':dates,
'Article':articles,
'URL':article_urls,
'PressCompany':press_companies})
article_df.to_excel('result_{}.xlsx'.format(datetime.now().strftime('%y%m%d_%H%M')), index=False, encoding='utf-8')
print('\n크롤링이 성공적으로 완료되었습니다!')
print('\n크롤링 결과를 다음 파일에 저장하였습니다 : {}'.format(datetime.now().strftime('%y%m%d_%H%M')))
query = input('검색어를 입력해주세요. (ex. 데이터 분석) : ')
start_date = input('검색 시작 날짜를 입력해주세요. (형식 : 2021.01.01) : ')
end_date = input('검색 종료 날짜를 입력해주세요. (형식 : 2021.12.31) : ')
sort_type = input('정렬 타입을 입력해주세요 (관련도순 = 0, 최신순 = 1, 오래된순 = 2) : ')
max_page = input('크롤링을 원하는 전체 페이지 수를 입력해주세요. (ex. 5) : ')
if start_date > end_date:
print('\n시작 날짜는 종료 날짜보다 이후로 지정하실 수 없습니다. 다시 실행해주세요!')
elif max_page == '':
max_page = 5
print('\n원하시는 페이지 수가 입력되지 않았습니다. 5 페이지까지만 크롤링을 진행합니다.')
main_crawling(query, start_date, end_date, sort_type, max_page)
else:
max_page = int(max_page)
main_crawling(query, start_date, end_date, sort_type, max_page)
검색어를 입력해주세요. (ex. 데이터 분석) : 인공지능
검색 시작 날짜를 입력해주세요. (형식 : 2021.01.01) : 2022.01.01
검색 종료 날짜를 입력해주세요. (형식 : 2021.12.31) : 2023.02.01
정렬 타입을 입력해주세요 (관련도순 = 0, 최신순 = 1, 오래된순 = 2) : 0
크롤링을 원하는 전체 페이지 수를 입력해주세요. (ex. 5) : 4
1번째 기사글부터 크롤링을 시작합니다.
Processing article : 업스테이지, 한화생명에 인공지능 광학문자인식 솔루션 공급
Processing article : 인공지능으로 24시간 산불 탐지해 헬기·드론·진화차로 끈다
Processing article : 양자·인공지능 연구 날개 달 초저전력 차세대 트랜지스터 개발
Processing article : 롯데온, KT와 손잡고 '인공지능 운송 플랫폼' 도입
Processing article : 인공지능기술교육협의회·한국마이크로소프트 인재양성 업무협약 체결
Processing article : 코바코, 인공지능이 광고제작 'AI 카피라이팅' 지원
Processing article : 어니스트펀드, 인공지능 기반 데이터 분석 및 개발 솔루션 상용화
11번째 기사글부터 크롤링을 시작합니다.
Processing article : LG, '챗GPT'처럼 이미지 이해하고 설명하는 인공지능 키운다
Processing article : 챗GPT 만든 오픈AI사, 인공지능글 감별 도구 발표
Processing article : 아모레퍼시픽, 인공지능기술 활용… ‘개인 맞춤’ 화장품 출시
Processing article : KT, 롯데온과 손잡고 인공지능 운송 플랫폼 도입
Processing article : 코바코, 인공지능이 광고제작 'AI 카피라이팅' 지원
Processing article : 부산도시공사, 인공지능 활용 스마트홈 전문가 초청 특강
Processing article : 하늘 사진 본 AI “붉은빛 어우러져”… LG ‘캡셔닝 인공지능’ 육성
21번째 기사글부터 크롤링을 시작합니다.
Processing article : 의회 연설문에 기사도 척척...美 의회 "인공지능 논의 착수해야"
Processing article : "사용자중심인공지능, 새로운 경제 질서로 성장 기여"
31번째 기사글부터 크롤링을 시작합니다.
Processing article : "인공지능 시대, 빅테크 기업의 데이터 독과점 안돼"
Processing article : 시설물 안전진단 때 로봇·인공지능(AI) 장비·드론 등 투입
Processing article : 인공지능이 쓴 시, 저작권이 없다? 왜
Processing article : 예산군 ‘인공지능 CCTV’ 시범운영
Processing article : 尹 "인공지능 챗GPT가 쓴 신년사 보니…훌륭하더라"
크롤링이 성공적으로 완료되었습니다!
크롤링 결과를 다음 파일에 저장하였습니다 : 230205_2046
df = pd.read_excel('result_230205_2.xlsx') # result_ TAB 하면 이전에 만들어놓았던 엑셀파일들이 나옴
df.head()
감사합니다.
파이썬을 이용한 네이버 뉴스 스크래핑 (1) (0) | 2023.02.05 |
---|---|
텍스트 데이터 분석 기초 복습 4 (Text Analysis) (0) | 2023.01.27 |
텍스트 데이터 분석 기초 복습 3 (Text Data Exploration) (1) | 2023.01.26 |
텍스트 데이터 분석 기초 복습 2 (TF-IDF, Cosine Similarity, 정규표현식) (0) | 2023.01.25 |
텍스트 데이터 분석 기초 복습 1 (Preprocessing Text Data) (0) | 2023.01.24 |