개발자식

[스크래핑] Web scraping for news articles (3) 본문

Data/Python

[스크래핑] Web scraping for news articles (3)

밍츠 2022. 3. 29. 00:36

네이버 뉴스에 검색어를 입력하여 스크래핑 한다.

 

import requests
from bs4 import BeautifulSoup

import pandas as pd
from datetime import datetime #현재날짜&시간 받아오기
import time
import re
def main_crawling(query, start_date, end_date, sort_type, max_page):
    
    if query == '':
        query = '데이터 분석'
    if len(start_date) != 10:
        start_date = '2021.01.01'
    if len(end_date) != 10:
        end_date = '2021.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://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('h3', {'id' : 'articleTitle'}).get_text()
                    print('Processing article : {}'.format(title))

                    date = source_news.find('span', {'class' : 't11'}).get_text()

                    article = source_news.find('div', {'id' : 'articleBodyContents'}).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('address', {'class' : 'address_cp'}).find('a').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~else문 함수에 넣는것이 낫다.
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) : 2022.03.28
정렬 타입을 입력해주세요 (관련도순 = 0, 최신순 = 1, 오래된순 = 2) : 0
크롤링을 원하는 전체 페이지 수를 입력해주세요. (ex. 5) : 5

1번째 기사글부터 크롤링을 시작합니다.
Processing article : 안철수 "정부 코로나19 대처 무책임…일회용컵 규제 유예해야"
Processing article : 코로나 속에서도 카드 사용액 9.5% 증가… 재난지원금 영향도
Processing article : 인수위 "尹정부, 코로나 백신 피해 국가 보상책임 확대"
Processing article : 광주은행 코로나 피해업체 지원 10억원 특별출연
Processing article : 광주, 코로나 4차 접종률 20.9% 특·광역시 중 최고
Processing article : 정부, 동네 병·의원으로 코로나 대면진료 확대
Processing article : 김창룡 경찰청장 오늘 코로나19 확진… 모든 일정 취소(상보)
Processing article : 尹 측, 청와대 회동에 “코로나 손실보상 문제 가장 시급”
Processing article : 코로나·이자·원자재 값 '삼중고', 수출기업 목 죈다
Processing article : 코로나19·독감 동시에 걸리면 '사망위험 2.4배' 치솟는다

11번째 기사글부터 크롤링을 시작합니다.
Processing article : 몇달째 지속되는 코로나19 증상…'롱 코비드' 비상
Processing article : 코로나·이자·원자재 값 '삼중고', 수출기업 목 죈다
Processing article : 테슬라, 코로나 봉쇄로 상하이 공장 생산 중단
Processing article : 피로감·숨가쁨 호소에…당국, 코로나 후유증 조사 추진
Processing article : 코로나19 확진자도 동네 병원서 대면진료 받는다
Processing article : 유은혜 부총리 코로나19 확진…4월 2일까지 격리·치료
Processing article : 코로나19·독감 동시에 걸리면 '사망위험 2.4배' 치솟는다
Processing article : 코로나 끝나나 했더니… 전문가들 "더 나쁜 변이 나타나"
Processing article : 증상 있어도 "나 코로나 아냐" 버티던 직원 탓에…줄줄이 확진
Processing article : 中 상하이, 코로나 확산에 전면봉쇄…“방해하면 책임 추궁”

21번째 기사글부터 크롤링을 시작합니다.
Processing article : 尹측 "文대통령 만찬, 코로나 손실보상 적극 협조 요청"
Processing article : 문체부, 문화예술인 4만명 활동지원…“코로나 장기화로 인한 조치”
Processing article : 재산 4800억인데…'코로나 지원금' 20억 받은 미술가
Processing article : AZ 코로나 항체 복합제 '이부실드' 유럽 승인
Processing article : "회사 대표가 코로나 미감염자에게만 상여금 준답니다"
Processing article : 안철수 “코로나 잠잠해질 때까지 일회용컵 규제 유예해야”
Processing article : 대선 후 19일 만에 文-尹 회동..."코로나19 손실 보상 논의"
Processing article : “신규확진 2주 내 30만명 미만”…당국, 코로나 유행 감소세 전망
Processing article : [코로나19]신규확진 13만명 급감 18만7213명…25일 만에 20만명↓
Processing article : 문 대통령-윤 당선인, 오늘 靑 만찬…“코로나 보상 시급”

31번째 기사글부터 크롤링을 시작합니다.
Processing article : 尹, 日대사에 "한·일관계 복원 시급…코로나 괜찮으시냐"

*** 31번부터 40번까지의 기사글을 크롤링하는 중 문제가 발생했습니다.
*** 다음 링크의 뉴스를 크롤링하는 중 에러가 발생했습니다 : https://news.naver.com/main/read.naver?mode=LSD&mid=sec&sid1=106&oid=003&aid=0011087731
Processing article : 국세청 "코로나19 극복 지원·기업 세무조사 제외 확대"…인수위 업무보고
Processing article : 테슬라, 2년만에 또 주식분할 추진…머스크는 코로나 확진
Processing article : 코로나 위중증 1273명 ‘역대 최다’…사망 287명
Processing article : 코로나 중환자 최대 1300~1680명…"4월 돼야 감소"
Processing article : 코로나 걸렸을 땐 독감 더 조심해야…둘다 걸리면 사망률 2.4배
Processing article : 아산시 코로나19 검사 이순신운동장서 통합 운영
Processing article : 中 코로나 감염 하루 6000명대, 상하이도 결국 도시 봉쇄

41번째 기사글부터 크롤링을 시작합니다.
Processing article : 2500만명 전수검사 한다고? 중국 상하이 '코로나 셧다운'
Processing article : 코로나19 신규 확진자 오후 6시까지 24만4419명…어제보다 8만6869명↑
Processing article : 올여름 코로나 새 변이 찾아온다?…전문가들 "오미크론보다 강할 수도"

*** 41번부터 50번까지의 기사글을 크롤링하는 중 문제가 발생했습니다.
*** 다음 링크의 뉴스를 크롤링하는 중 에러가 발생했습니다 : https://news.naver.com/main/read.naver?mode=LSD&mid=sec&sid1=106&oid=009&aid=0004940949
Processing article : 코로나19 신규 확진자 오후 9시까지 33만3951명…어제보다 15만명↑
Processing article : 법무부, 외국인근로자 13만명 체류연장…코로나 인력난 대응
Processing article : 중수본 "코로나 1급 감염병 제외, 큰 사안이라 시간 걸릴 것"
Processing article : 확진자 “눈이 이상해요”…코로나 증상, 눈에도 나타난다
Processing article : 尹인수위, "코로나 확산 지속...규제 유예 추진"
Processing article : 文-尹 대선 19일만에 회동…최우선 의제 '코로나 2차 추경'

크롤링이 성공적으로 완료되었습니다!

크롤링 결과를 다음 파일에 저장하였습니다 : 220329_0020

결과가 맞는지 확인 :

Comments