파이썬으로 네이버 뉴스 기사 수 크롤링

파이썬으로 네이버 뉴스 기사 수 크롤링

파이썬 언어를 이용하여 네이버에서 특정 영화와 관련된 뉴스 컨텐츠들의 갯수를 크롤링하는 방법에 알아봅시다.


우선 사용할 패키지들에 대해서 먼저 언급하면

1
2
requests
Beautifulsoup

입니다. 사전에 설치가 된 상태로 진행하시길 바랍니다.

또한 검색 중에 크롬 개발자 도구를 사용하므로 Google Chrome 브라우저를 사용하시길 바랍니다.


특정 검색 사이트에서 크롤링을 시작할 때는 먼저 해당 사이트에서 검색을 해보는 것이 중요합니다.

해당 사이트에서의 검색 결과가 어떻게 도출 되는지 확인하기 위해서 입니다.

2016년에 개봉한 곡성영화에 대해 검색해 봅시다.

검색결과


그림과 같이 곡성군청에 관한 주소와 우리가 원하는 영화 곡성에 대한 정보가 나타납니다.

일단 단순 검색 했을 시 그림처럼 나타날 뿐 우리가 원하는 뉴스 검색 기사 수는 뉴스 탭을 클릭해보면


뉴스 검색

실제로 한국에는 곡성군 지역이 있기에 우리가 원하는 영화에 대한 기사는 한참 뒤로 가려져 있는 듯 합니다.

(물론 검색한 시점이 영화가 개봉한 지 2년이나 지난…)

또한 무려 10만건의 기사수가 나타난 것을 알 수 있습니다.

그렇다면 영화명만 검색하지 말고

영화명+감독명 을 같이 검색한다면 어떻게 나타나는지 봅시다.

검색 영화명+감독

다행이 우리가 원했던 검색 기사 수를 받을 수 있게 되었습니다.

또한 9105건의 기사 수로 확연히 달라짐을 알 수 있게 되었습니다.


뉴스 기사 건 수는 검색결과에서 중간 즈음에 빨간색으로 표시된 부분

기사 수

부분에서 알 수 있습니다.

자, 이제 크롬 개발자 도구를 이용하여 이 웹페이지를 분석해볼 것입니다.

크롬을 연상태에서 F12 키를 입력하면 개발자 도구가 나타납니다.

3

음.. 뭔가 복잡해 보이지만 우리가 사용할 도구는 왼쪽 상단에

마우스 모양의 도구를 이용할 것입니다.



마우스 도구를 이용하여 마우스를 페이지상에 옮겨 다니면

마우스가 올려진 부분에 대한 html 소스코드가 개발자 도구에서 하이라이트 쳐진 상태로 나타납니다.


여기서 우리는 뉴스 기사 수에 관한 부분으로 마우스를 올려 보면

기사 수에 대한 부분의 html 코드를 자동으로 찾아 줍니다. (갓 크롬…)

보시면 <span>태그 사이에 존재하고

상위에는 <div class="title_desc all_my">태그가 감싸고 있습니다. (메모…)



이제 네이버에서 검색한 웹 주소를 복사해 둡시다.

1
https://search.naver.com/search.naver?sm=tab_hty.top&where=news&query=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&oquery=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&tqi=TFtVlspySDwsstafcKhssssst4d-093118

여기까지 진행한 것은 우리가 파이썬 코드로 웹 페이지의 html 태그를 읽고

우리가 원하는 데이터만을 뽑기위한 길 찾기?작업을 한것이라고 할 수 있습니다.


크롤링할 데이터의 위치를 알아 냈으니 이제 코드를 작성해봅시다.


우선 파이썬 파일을 생성하고

1
2
import requests
from bs4 import BeautifulSoup

를 입력합니다.

requests 패키지를 이용하여 http 요청을 실행하고 (웹 요청)

BeautifulSoup 패키지를 이용하여 html 소스를 읽을 것입니다.

이제 주소를 담은 url변수를 만들고

1
2
3
4
import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?sm=tab_hty.top&where=news&query=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&oquery=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&tqi=TFt3wdpySD0ssvkgAFCssssstbh-278429"

requests.get을 이용하여 http get요청을 실행 할 수 있습니다.

1
2
3
4
5
6
import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?sm=tab_hty.top&where=news&query=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&oquery=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&tqi=TFt3wdpySD0ssvkgAFCssssstbh-278429"

req = requests.get(url)

print(req)를 해보면 응답코드를 확인할 수 있습니다. 정상 응답은 코드가 200이면 요청이 성공한 것 입니다.

1
2
3
4
5
6
7
import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?sm=tab_hty.top&where=news&query=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&oquery=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&tqi=TFt3wdpySD0ssvkgAFCssssstbh-278429"

req = requests.get(url)
print(req)

실행결과:

오류해결

403응답으로 즉,서버가 요청을 거부한 상태입니다. HTTP 403 응답이란

HTTP요청을 보낼때는 Header라는 부가적인 정보를 담아 보냅니다.

서버는 이 헤더 정보를 통해 정상적인 유저의 접근인가를 확인하는데 이 헤더정보를 담아서 요청을 보내봅시다.

requests.getheaders라는 옵션을 추가하고 변수를 추가시킵시다.

1
2
3
4
5
6
7
8
9
10
11
import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?sm=tab_hty.top&where=news&query=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&oquery=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&tqi=TFt3wdpySD0ssvkgAFCssssstbh-278429"

header = {
'User-Agent': 'Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; ko-KR))',
}

req = requests.get(url,headers=header)
print(req)

실행결과:

드디어 정상적인 접근이 성공 했습니다.

print(req) 부분을 print(req.content)로 수정시키면 페이지 코드를 찍을 수 있습니다.

이제 BeautifulSoup로 html코드를 읽읍시다.

1
2
3
4
5
6
7
8
9
10
11
import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?sm=tab_hty.top&where=news&query=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&oquery=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&tqi=TFt3wdpySD0ssvkgAFCssssstbh-278429"

header = {
'User-Agent': 'Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; ko-KR))',
}

req = requests.get(url, headers=header)
soup = BeautifulSoup(req.content, 'html.parser')

req.contentrequests를 통해 받은 페이지 정보를 가지고 있고

html.parser로 html 인코딩 시킵니다.

BeautifulSoup는 여러가지 기능을 제공하는데 우리는 find옵션을 사용합니다.

soup.find는 html소스로 부터 입력한 파라미터의 정보를 찾아줍니다.

위에서 우리는 <div class="title_desc all_my">태그 사이에 데이터를 가져올 수 있으므로

아래와 같이 파라미터를 설정합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?sm=tab_hty.top&where=news&query=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&oquery=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&tqi=TFt3wdpySD0ssvkgAFCssssstbh-278429"

header = {
'User-Agent': 'Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; ko-KR))',
}


req = requests.get(url, headers=header)
soup = BeautifulSoup(req.content, 'html.parser')
data = soup.find('div', class_='title_desc all_my')
print(data)

실행결과:

여전히 <span>태그로 감싸고 있습니다.

우리는 .text 를 붙여서 태그들 사이의 텍스트 정보만 가져올 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?sm=tab_hty.top&where=news&query=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&oquery=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&tqi=TFt3wdpySD0ssvkgAFCssssstbh-278429"

header = {
'User-Agent': 'Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; ko-KR))',
}


req = requests.get(url, headers=header)
soup = BeautifulSoup(req.content, 'html.parser')
data = soup.find('div', class_='title_desc all_my').text #.text추가
print(data)

실행결과:

음… 여전히 수정이 필요합니다.

거슬리는 부분을 제거하기 위해 아래 방식으로 수정합시다.

또한 에러등을 잡기 위해 try excep 문을 추가하였습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?sm=tab_hty.top&where=news&query=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&oquery=%EA%B3%A1%EC%84%B1+%EB%82%98%ED%99%8D%EC%A7%84&tqi=TFt3wdpySD0ssvkgAFCssssstbh-278429"

header = {
'User-Agent': 'Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; ko-KR))',
}

try:
req = requests.get(url, headers=header)
soup = BeautifulSoup(req.content, 'html.parser')
data = soup.find('div', class_='title_desc all_my').text
data = data[7:-1]
data = data.replace(',', '')
print(data)
except Exception as e:
print(e)

실행결과:

파이썬의 data[:] 는 문자열 포맷하는 방법으로

data[시작부분:끝부분]으로 문자열을 포맷합니다. 즉

1-10 / 9,105건이라는 문자열의 앞부분 1-10 /을 건너띄고 부분을 지우는 것입니다.

문자열을 포맷하고 나면 9,105가 남게 되는데

replace,콤마를 빈값으로 바꿉니다. 따라서 최종적으로 9105 문자열이 완성되는 것입니다.

unsplash-logoKristijan Arsov

댓글