본문 바로가기

기타/python

파이썬 웹 크롤링 urllib과 BeautifulSoup 예제(2)

728x90

전 시간에는 기본적인 사용법을 알아보았다면 오늘은 조금 더 디테일하고 많은 양의 웹데이터를 크롤링하도록 하겠습니다.

우리의 목표는 네이버에서 미국 대선이라는 검색어를 검색했을 때 네이버 뉴스로 된 포맷이 있는 링크만 가져와 보도록 하겠습니다.

분석에 앞서 우선 해당 페이지의 url과 html 코드를 분석해봐야 합니다.

가져오려고 하는 데이터가 가진 특징을 찾아야 하니까요. id, class 같은 것들을 알아야 합니다.

 

네이버에서 미국 대선을 검색해보도록 하죠.

우리의 미션은 아래와 같은 기사가 있다고 했을 때, 기사 옆에 '네이버 뉴스'라고 되어 있는 부분의 url을 가져오는 것입니다.

다음으로 해야 할 것은 '네이버 뉴스'라고 된 부분이 가진 고유의 특성을 찾는 것입니다.

페이지 검사를 통해 보도록 하죠.
3가지의 공통점을 찾아볼까요? 우선 url에 'https://news.naver.com/main/read.nhn'이 있습니다. 

메인 기사의 경우 info, 서브 기사의 경우 sub_txt가 있네요.

이 두 가지 특징을 기반으로 데이터를 가져오면 됩니다.

 

 

 

첫 번째 조건인 https://news.naver.com/main/read.nhn로 시작한다는 것은 어떻게 검증할 수 있을까요?

문자열을 검색하는 것이니 정규표현식을 쓰는 것이 좋습니다.

두 번째 조건은 a태그의 class가 info, subtxt라는 것입니다.

 

이 두 가지 조건을 활용하여 크롤링하면 우리가 원하는 네이버 뉴스 포맷으로 된 기사들의 링크를 가져올 수 있습니다.

 

다음으로 해야 할 것은 무엇일까요?

검색하고 맨 아래에 가면 이렇게 기사 페이지가 나옵니다.

보통 한 페이지에 10개의 기사가 나옵니다.

 

 

 

'search.naver.com/search.naver?sm=tab_hty.top&where=news&query=%EB%AF%B8%EA%B5%AD%EB%8C%80%EC%84%A0&oquery=%EB%AF%B8%EA%B5%AD%EB%8C%80%EC%84%A0&tqi=UIhDHdp0YiRssUbXvb0ssssst50-384010'

네이버에서 미국 대선을 감색하면 위와 같은 링크로 검색이 이루어집니다.

우리가 알아야 할 것은 기사 페이지가 어디까지 이어져 있나입니다.

그것을 알기 위해서는 url의 특징을 파악해야 합니다.

위의 url로는 특징을 파악하기 힘듭니다.

페이지수가 나오는 곳에서 1,2,3을 순서대로 눌러보도록 하지요.

search.naver.com/search.naver?&where=news&query=%EB%AF%B8%EA%B5%AD%EB%8C%80%EC%84%A0&sm=tab_pge&sort=0&photo=0&field=0&reporter_article=&pd=0&ds=&de=&docid=&nso=so:r,p:all,a:all&mynews=0&cluster_rank=30&start=1&refresh_start=0

search.naver.com/search.naver?&where=news&query=%EB%AF%B8%EA%B5%AD%EB%8C%80%EC%84%A0&sm=tab_pge&sort=0&photo=0&field=0&reporter_article=&pd=0&ds=&de=&docid=&nso=so:r,p:all,a:all&mynews=0&cluster_rank=61&start=11&refresh_start=0

search.naver.com/search.naver?&where=news&query=%EB%AF%B8%EA%B5%AD%EB%8C%80%EC%84%A0&sm=tab_pge&sort=0&photo=0&field=0&reporter_article=&pd=0&ds=&de=&docid=&nso=so:r,p:all,a:all&mynews=0&cluster_rank=81&start=21&refresh_start=0

 

어떤 부분이 변했는지 그것의 의미는 무엇인지 생각해 보아야 합니다.

 

굵은 글씨로 된 곳을 보면 페이지 1은 1로 시작하고 2는 11, 3은 21로 시작합니다.

한 개의 페이지에 10개의 글이 있다는 사실을 직관적으로 느낄 수 있습니다.

1,2,3페이지에서 마지막 페이지에 대한 정보를 알 수 없습니다.

그렇다면 start을 큰 수로 넣어 검색해 보도록 하겠습니다.

10000을 넣어보죠.

400페이지를 끝으로 더 이상 넘길 수 없습니다.

존재하는 기사수보다 큰 수를 넣으면 마지막 페이지로 안내해 준다는 사실을 알 수 있습니다.

여기서 400을 눌러보도록 하죠.

start=3991

를 알 수 있습니다. 미국 대선 관련 기사수는 총 4000개라는 사실을 알 수 있습니다.

start부분을 1부터 시작해 10씩 증가시켜 3991까지 하면 모든 기사 페이지를 가져올 수 있는 것입니다.

이렇게 가져온 페이지에서 위에서 발견한 두 가지 특성을 적용해 크롤링하면 네이버 뉴스 포맷으로 된 기사의 링크를 모두 가져올 수 있습니다.

cluster_rank도 계속해서 바뀝니다.

이점은 여러분이 직접 찾아보시기 바라요 ㅎㅎㅎ

무엇을 의미하는지요.

힌트 코드는 아래와 같습니다.

url부분을 적당히 수정하면 원하는 값을 얻으실 수 있을 겁니다.

 

import urllib.request
import urllib.parse 
from bs4 import BeautifulSoup
import re

key_words=urllib.parse.quote("미국대선")
searchtext=re.compile('^http(s)?:\/\/(news)\.(naver)\.(com)\/(main)\/(read)\.(nhn)')
new_link_2=[]
k=1
while k!=4001: 
    with urllib.request.urlopen('https://search.naver.com/search.naver?where=news&query='
                            +key_words
                            +'&sm=tab_opt&sort=0&photo=0&field=0&reporter_article=&pd=3&ds=2020.11.06&de=2019.11.07&docid=&nso=so:r,p:from20191013to20191014,a:all&mynews=0&cluster_rank=26&start'
                                +str(k)+'&refresh_start=0') as response:
        data=(response.read())
    soup = BeautifulSoup(data, 'html.parser')
    anchor_set=soup.find_all("a",{'class':['info','sub_txt']})

    for i in anchor_set:
        try :
            if searchtext.match(str(i['href'])) != None:
                new_link_2.append(i['href'])
        except :
            pass
    print(len(new_link_2))
    k+=10

 

중요한 것은 이것을 푸는 것이 아니라 과정을 이해하는 것입니다.

url, 페이지 html에서 가져올 데이터의 특성을 분석하는 과정이 가장 중요합니다.

 

얼마 전 네이버의 pc버전 디자인이 바뀌면서 이전의 크롤링 방식으로는 데이터를 가져오기 힘들어졌습니다.

이런 변화에 대응하기 위해서는 페이지에서 가져오려는 데이터의 특성을 파악하는 능력을 길러야 합니다.

크롤링의 핵심은 페이지 분석능력이라는 것입니다.

웹 프런트엔드에 대한 이해가 필요합니다.

728x90