Back to Posts

파이썬 크롤링 튜토리얼 - 5 : Beautiful Soup와 Selenium을 함께 사용하는 방법

Posted in crawl

Selenium으로 진입한 웹 사이트 크롤링하기

1. Facebook Profile로 접속할 준비하기

파이썬 크롤링 튜토리얼 - 4에서 페이스북에 로그인 하는 방법을 알아봤었습니다. 튜토리얼 - 4 에서 완성한 코드를 재검토해보고 시작하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
usr = "아이디"
pwd = "패스워드"

path = "/Users/hjvsdh/crawl/chromedriver"
driver = webdriver.Chrome(path)
driver.get("http://www.facebook.org")
assert "Facebook" in driver.title
elem = driver.find_element_by_id("email")
elem.send_keys(usr)
elem = driver.find_element_by_id("pass")
elem.send_keys(pwd)
elem.send_keys(Keys.RETURN)

오늘은 이 코드를 응용해서, 내 타임라인에 있는 글을 몇개 긁어와보려고 합니다. 우리가 사용하는 driver 가 profile에 접속할 수 있도록 profile 링크(href)를 찾아줘야하는데, 이전에 사용했던 선택자말고 XPath를 사용해볼겁니다.

프로필태그의 href값을 찾기 위해 아래 사진처럼 개발자모드에 들어가서 이 부분을 선택해줍니다. image 이 부분을 우클릭하고 Copy -> Copy XPath를 해줍니다.

그리고 4장에서 완성했던 코드 제일 끝에, 아래 코드를 입력합니다.

1
2
a = driver.find_elements_by_xpath('이곳에 Copy했던 XPath를 붙여넣습니다.')
driver.get(a[0].get_attribute('href'))

driver.find_elements_by_xpath XPath로 해당 elements 를 가져오는 겁니다. 기본적으로 a = find_elements_by_xpath 를 하게되면 a 는 list 상태가 되므로, a[0]을 한 뒤, get_attribute(‘href’)를 하는 겁니다. 그러면 elements 안에 있는 href(프로필 주소) 속성값으로 Web Driver 가 접속하게 되는겁니다.

이제 내 타임라인에 접근하는 것은 성공했습니다.

만약 XPath를 찾을 수 없다는 에러가 나오면, time 을 import 하여 Facebook 페이지가 원활히 로딩이 끝날때 까지 time.sleep(5)로 5초정도 기다려주면 해결됩니다. import time을 하고, elem.send_keys(Keys.RETURN)아래에 time.sleep(5)를 씁니다. UI가 로딩될 때 까지 기다리는 방법도 있습니다. 참고 문서

2. Facebook Profile에 있는 데이터 크롤링하기

페이스북 타임라인 포스트 크롤링같은 경우에는 Facebook Graph API를 사용하는게 훨씬 간결하고 편합니다. 하지만 우리가 크롤링하려는 부분은 바로 이 부분입니다. image 좌측에 위치한 소개 부분을 크롤링 할 겁니다. Web Driver 가 현재 실행중인 웹 사이트의 소스를 가져오려면 아래 소스를 입력해야 합니다.

req = driver.page_source

이렇게 req에 소스를 저장했으면 이 req가 HTML parser를 사용해야한다고 알려줘야합니다. 참고 : 파이썬 크롤링 튜토리얼 - 1. 그 전에 맨 윗쪽에 from bs4 import BeautifulSoup 를 해줘야겠죠?

soup=BeautifulSoup(req, 'html.parser')

그리고 선택자를 찾아내야 합니다. image Copy -> Copy Selector 을 하게 되면 div의 id가 하나 나옵니다. 그럼 튜토리얼 - 1 에서 처럼 출력이 되는지 확인하기 위해 코드를 입력해봅시다.

information_list = soup.select("#intro_container_id")
for information in information_list:
	print(information.text)

image 크롤링이 된게 확인이 됩니다!

최종 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import time
usr = "아이디"
pwd = "패스워드"

path = "/Users/hjvsdh/crawl/chromedriver"
driver = webdriver.Chrome(path)
driver.get("http://www.facebook.org")
assert "Facebook" in driver.title
elem = driver.find_element_by_id("email")
elem.send_keys(usr)
elem = driver.find_element_by_id("pass")
elem.send_keys(pwd)
elem.send_keys(Keys.RETURN)

a = driver.find_elements_by_xpath('//*[@id="u_0_a"]/div[1]/div[1]/div/a')
driver.get(a[0].get_attribute('href'))

req = driver.page_source
soup=BeautifulSoup(req, 'html.parser')
information_list = soup.select("#intro_container_id")
for information in information_list:
	print(information.text)
Read Next

jekyll 포스트에 Related Post를 추가하는 방법