파이썬을 이용하여 웹 크롤러 만들기 #2 - BeautifulSoup4을 활용하여 크롤링하기


안녕하세요. 남산돈가스입니다.

지난 포스팅에 이어 오늘은 두번째 순서인 BeautifulSoup4를 활용하여 웹 크롤링을 해보도록 하겠습니다.

우선, BeautifulSoup 이라는 것이 어떤 건지 간단히 말씀드리자면, html코드를 python이라는 언어가 이해할 수 있는 객체 구조로 변환해주는 대표적인 html Parsing 라이브러리입니다.

웹크롤링을 한다면 필수적인 라이브러리로 파이썬 웹크롤링 서적에서도 소개될 만큼 검증 된 라이브러리입니다.

이번 포스팅에선 대표적으로 requests 와 BeautifulSoup4 라이브러리를 이용해서 크롤링을 해보려고 합니다.

먼저 위에서 말씀드린 라이브러리들을 install 해보겠습니다.

터미널에 pip install beautifulsoup4 를 입력하여 beautifulSoup 라이브러리를 설치합니다.

$ pip install beautifulsoup4
Collecting beautifulsoup4
  Downloading https://files.pythonhosted.org/packages/9e/d4/10f46e5cfac773e22707237bfcd51bbffeaf0a576b0a847ec7ab15bd7ace/beautifulsoup4-4.6.0-py3-none-any.whl (86kB)
    100% |████████████████████████████████| 92kB 445kB/s
Installing collected packages: beautifulsoup4
Successfully installed beautifulsoup4-4.6.0

다음으로 requests 라이브러리를 install 합니다.

$ pip install requests
Requirement already satisfied: requests in /Users/gimseongsin/Library/Python/3.6/lib/python/site-packages

제 경우엔 이미 requests 라이브러리가 설치되어 있는 상태입니다.

이렇게 두가지 라이브러리를 설치하셨으면 준비가 끝났습니다.

웹크롤링을 가볍게 체험해보기 위해서 네이버 영화 순위 페이지에서 현재 상영작 중 1위의 영화제목을 크롤링하는 코드를 작성해보겠습니다.


실제 네이버영화 페이지에 들어가서 확인해보니 '어벤져스:인피니티 워' 가 1위를 달리고 있네요. 이 영화제목을 python코드에서 parsing 하는 과정을 소개해드리겠습니다.

저 text를 크롤링하기 위해선 기본적으로 필요한 정보가 있습니다. 먼저 해당 영화 랭킹 페이지의 url이 필요하고 저 페이지 안에 있는 무수히 많은 html tag 중 저 1위에 해당하는 영화제목이 위치하고 있는 html tag의 식별자가 필요합니다.

페이지 url이야 위 화면에서 주소창에서 복사하면 'https://movie.naver.com/movie/sdb/rank/rmovie.nhn' 이라는 주소를 얻을 수 있습니다.

그런데 저 복잡한 페이지 안에서 1위에 해당하는 영화제목 html 식별자를 어떻게 알수있을까 싶은데요.

크롬브라우저로 설명드리자면, 브라우저 자체적으로 제공하는 '개발자 도구'를 통해 쉽게 식별자를 얻을 수 있는데요. 아래 사진에서 오른쪽에 탭이 올라와있는 것이 '크롬 개발자 도구'입니다. 


위 사진에서 빨간 네모 부분을 클릭한 뒤 현재 1위인 영화제목쪽으로 마우스 커서를 대보면 자동적으로 html코드에서 해당하는 부분의 위치를 찾아옵니다. 아래 사진에서 찾아온 위치 왼쪽에 더보기 메뉴를 클릭하여 아래처럼 Copy > Copy selector 를 클릭하면 자동으로 클립보드에 해당 html 식별자를 복사합니다.

저 위치를 실제로 확인해보면 ''#old_content > table > tbody > tr:nth-of-type(2) > td.title > div > a' 를 확인하실 수 있습니다.


이제 두 가지 정보를 가지고 실제 python 코딩을 통해 크롤링을 해보겠습니다.

import requests
from bs4 import BeautifulSoup

res = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.nhn')

print(res)  # <Response [200]>]
soup = BeautifulSoup(res.text, 'html.parser');

main_news = soup.select_one('#old_content > table > tbody > tr:nth-of-type(2) > td.title > div > a').text

print(main_news);


소스 코드는 다음과 같이 단 10줄 이내로 끝났습니다.

간단하게 설명드리자면, 첫 번째로 requests와 BeautifulSoup 라이브러리를 사용하기 위해 import 해줬습니다.

그 다음으로, 아까 영화 랭킹페이지 정보를 requests 객체를 이용하여 load했고, res 라는 변수에 해당 결과값을 저장하였습니다.

그 res를 print()함수를 이용하여 출력시켜 보면 <Response [200]> 이라는 결과를 확인할 수 있는데요. 200이라는 코드는 http 코드에서 성공상태를 의미합니다. 200이라는 결과를 확인하면 정상적으로 해당 페이지 정보를 가지고왔다고 이해하시면 됩니다.

그 다음에서 성공적으로 load된 res객체를 BeautifulSoup 객체에 담아 html 파싱을 진행하고 그 결과를 soup이라는 변수에 담았습니다.

여기까지 진행한 결과는 영화랭킹 페이지의 html소스코드를 BeautifulSoup을 통해 모두 파싱한 상태입니다.

이제 마지막으로 이 전체 페이지의 html에서 1위에 해당하는 영화제목을 가져와야 하므로, 아까 copy 해두었던 식별자를 가지고 검색을 하면 모든 것이 끝나게 됩니다.

이에 해당하는 함수로, select_one을 사용하는데, 이 매서드는 오직 1개의 결과만 출력해주는 기능입니다. 만약 검색할 내용이 여러 건이라면, select 매서드를 사용하시기 바랍니다.

저는 여기서 단 1건의 결과값을 검색하려했으므로 select_one을 사용하여 검색을 한 뒤 맨 뒤에 .text 속성에 접근하여 html 태그가 가지고있는 실제 text를 출력하도록 코딩했습니다.

위 소스코드를 작성한 뒤 명령줄 인터페이스에 $ python '실행 파일명.py' 으로 실행시켜 보면


'어벤져스: 인피니티 워' 로 1위 영화제목을 가져올 수 있었습니다.


지금은 간단하게 1건에 대한 내용을 가져와봤는데, 해당 페이지에 대한 html 구조 분석과 목적을 구체적으로 정의하고 크롤링을 진행한다면, 더욱 복잡한 페이지 또한 다룰 수 있습니다.

감사합니다.



댓글

주간 인기글

[앱 디자인] 디자인 가이드 만들기 - 안드로이드

남산 케이블카 이야기

[AWS] Bastion Host 를 활용한 SSH 접근통제 #1

[정보] 인스타그램은 당신의 소리를 '듣고' 있을 수도 있습니다

AWS Beanstalk 구성파일(.ebextensions)을 사용하여 환경 구성하기