DevSSOM

파이썬 크롤링 실습 - 네이버 뉴스 섹션들 기사 내용 추출하기 본문

Python/크롤링

파이썬 크롤링 실습 - 네이버 뉴스 섹션들 기사 내용 추출하기

데브쏨 2021. 7. 3. 19:46
반응형

네이버 뉴스 기사내용 추출하기

 

이전 글에 이어서 이번엔 기사 내용까지 추출하는 실습. 마찬가지로 네이버 뉴스 속보 페이지에서 실습을 진행.

사용 url :https://news.naver.com/main/list.nhn

 

언론사별 속보 뉴스

언론사별 속보 뉴스를 제공합니다.

news.naver.com

이번에는 특정 분야를 입력받으면 해당 분야의 속보 기사들의 href를 얻고, 그 href로 각각의 기사로 접근하여 기사의 내용을 크롤링해보겠음.

 

출력 예시

["특정 분야의 기사 내용 1", "특정 분야의 기사 내용 2"... ]

해야할 것

get_request, get_href, crawling 함수를 올바르게 구현하기

  1. get_request : 문자열 형태의 분야 이름이 매개변수로 주어지면, 해당 분야의 뉴스 속보 홈페이지의 GET 요청의 응답을 반환해야 함.
  2. get_href : get_request 함수로부터 특정 분야에 대한 GET 요청의 응답을 올바르게 받았다면, get_href는 분야별 속보 기사에 접근할 수 있는 href를 리스트로 반환해야 함.
  3. crawling : get_href 함수로부터 얻은 각 기사의 href로 기사에 접근하여 기사의 내용을 리스트로 반환해야 함.

 

>>>

 

기사 내용에 해당하는 HTML 태그를 크롬 개발자도구에서 확인.

<div class="_article_body_contents"> 안에 기사 내용들이 들어있는 걸 확인.

import requests
from bs4 import BeautifulSoup

def crawling(soup) :
    # 기사에서 내용을 추출하고 반환
    div = soup.find("div", class_="_article_body_contents")
    
    result = div.get_text()
    
    print(result)
    return None

def get_href(soup) :
    # 각 분야별 속보 기사에 접근할 수 있는 href를 리스트로 반환
    
    result = []
    
    div = soup.find("div", class_="list_body newsflash_body")
    
    for dt in div.find_all("dt", class_="photo"):
        result.append(dt.find("a")["href"])
    
    return result

def get_request(section) :
    # 입력된 분야에 맞는 request 객체를 반환
    # 아래 url에 쿼리를 적용한 것을 반환
    custom_header = {
        'referer' : 'https://www.naver.com/',
        'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
    }
    
    url = "https://news.naver.com/main/list.nhn"
    
    sections = {
        "정치" : 100,
        "경제" : 101,
        "사회" : 102,
        "생활" : 103,
        "세계" : 104,
        "과학" : 105
    }
    
    req = requests.get(url, headers = custom_header,
            params = {"sid1" : sections[section]}) # params 매개변수를 올바르게 설정
    
    return req
    

def main() :
    custom_header = {
        'referer' : 'https://www.naver.com/',
        'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
    }
    
    list_href = []
    result = []
    
    # 섹션을 입력
    section = input('"정치", "경제", "사회", "생활", "세계", "과학" 중 하나를 입력하세요.\n  > ')
    
    req = get_request(section)
    soup = BeautifulSoup(req.text, "html.parser")
    
    list_href = get_href(soup)
    
    for href in list_href :
        href_req = requests.get(href, headers = custom_header)
        href_soup = BeautifulSoup(href_req.text, "html.parser")
        result.append(crawling(href_soup))
    print(result)


if __name__ == "__main__" :
    main()

 

근데, 바로 기사 내용이 나오는게 아니라 줄이 많이 띄어져있잖아. 개행문자가 많은 것 같애. '// flash 오류를 우회하기 위한 함수 추가' 이런것도 끼어있고. 그래서 정리를 좀 해줄게.

 

우선 result에 있는 개행문자부터 제거. 

result = div.get_text().replace("\n", "")

그 다음에 '// flash 오류를 우회하기 위한 함수 추가' 제거.

    result = div.get_text().replace("\n", "").replace("// flash 오류를 우회하기 위한 함수 추가function _flash_removeCallback() {}", "")

실행 결과를 또 보다보면 탭 문자가 간간히 껴있어. 그럼 탭 문자도 없애줘.

    result = div.get_text().replace("\n", "").replace("// flash 오류를 우회하기 위한 함수 추가function _flash_removeCallback() {}", "").replace("\t", "")

그럼 깔끔하게 됐으니까 각각의 뉴스 기사들을 result 리스트 안에 넣어서 정리를 해줘.

 

최종 코드

import requests
from bs4 import BeautifulSoup

def crawling(soup) :
    # 기사에서 내용을 추출하고 반환
    div = soup.find("div", class_="_article_body_contents")
    
    result = div.get_text().replace("\n", "").replace("// flash 오류를 우회하기 위한 함수 추가function _flash_removeCallback() {}", "").replace("\t", "")
    
    return result

def get_href(soup) :
    # 각 분야별 속보 기사에 접근할 수 있는 href를 리스트로 반환
    
    result = []
    
    div = soup.find("div", class_="list_body newsflash_body")
    
    for dt in div.find_all("dt", class_="photo"):
        result.append(dt.find("a")["href"])
    
    return result

def get_request(section) :
    # 입력된 분야에 맞는 request 객체를 반환
    # 아래 url에 쿼리를 적용한 것을 반환
    custom_header = {
        'referer' : 'https://www.naver.com/',
        'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
    }
    
    url = "https://news.naver.com/main/list.nhn"
    
    sections = {
        "정치" : 100,
        "경제" : 101,
        "사회" : 102,
        "생활" : 103,
        "세계" : 104,
        "과학" : 105
    }
    
    req = requests.get(url, headers = custom_header,
            params = {"sid1" : sections[section]}) # params 매개변수를 올바르게 설정
    
    return req
    

def main() :
    custom_header = {
        'referer' : 'https://www.naver.com/',
        'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
    }
    
    list_href = []
    result = []
    
    # 섹션을 입력
    section = input('"정치", "경제", "사회", "생활", "세계", "과학" 중 하나를 입력하세요.\n  > ')
    
    req = get_request(section)
    soup = BeautifulSoup(req.text, "html.parser")
    
    list_href = get_href(soup)
    
    for href in list_href :
        href_req = requests.get(href, headers = custom_header)
        href_soup = BeautifulSoup(href_req.text, "html.parser")
        result.append(crawling(href_soup))
    print(result)


if __name__ == "__main__" :
    main()

 

728x90
반응형
댓글