★ 아직 많이 부족합니다. 댓글을 통한 가르침 환영입니다. ★

 

이번에는 Selenium(셀레니움)을 이용해서 크롤링을 해보겠습니다.

 

Selenium은 기본적으로 Webdriver을 활용하여 웹앱을 테스트하는데 주로 사용됩니다.

 

이전 포스팅에서는 BeautifulSoup을 활용하여 크롤링을 해왔었는데, BeautifulSoup은 유튜브 메인페이지처럼 스크롤을 내리면 계속 추가되는 내용까지 가져오기 어렵기 때문에 이 부분을 Selenium을 통해 가져와보도록 하겠습니다. (무한스크롤이라고 하죠..)

 

Youtube 페이지를 내려가며, 여기에 있는 모든 동영상의 제목을 크롤링해오는 것을 해보도록 하겠습니다.

 

먼저, Selenium을 설치해줍니다.

 

pip install selenium  

 

그리고, Webdriver을 다운받아줍니다.

 

Chrome :  https://sites.google.com/a/chromium.org/chromedriver/downloads 

 

Firefox :  https://github.com/mozilla/geckodriver/releases 

Edge :  https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

 

저는 chrome으로 진행하겠습니다만, 더 선호하시는 webdriver을 설치하여 진행하시면 됩니다.

 

이후, 편의상 다운받은 webdriver을 코드를 작성하는 directory로 이동시키겠습니다.

 

꼭 이동시키지 않아도 webdriver의 경로를 명시해주면 webdriver가 구동이 됩니다.

 

이제 코드를 작성해보도록 하겠습니다.

 

1
2
3
4
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import time
cs

 

먼저 위와 같이 3개의 라이브러리를 import 해주겠습니다.

 

이유는 아래에 하나하나 설명해가겠습니다.

 

그 다음,

 

1
driver = webdriver.Chrome('webdriver 경로')
cs

 

를 적어주시면 됩니다.

 

만약, 다운로드 받은 webdriver가 같은 폴더 내에 있을 경우에는

 

1
driver = webdriver.Chrome()
cs

 

만 해도 동작이 됩니다.

 

그 다음, 동작 된 webdriver가 실행할 url 주소를 다음과 같이 작성해줍니다.

 

1
2
3
driver.get('https://www.youtube.com/')
 
time.sleep(1)
cs

 

그리고 time 라이브러리를 import 한 이유는, 유튜브 url이 충분히 켜질 시간을 주는 역할을 합니다.

 

다음에는 켜진 youtube 페이지의 html 영역의 body를 스크롤을 충분히 내려주는 과정을 작성하겠습니다.

 

즉, youtube 페이지에 접속해서 스크롤을 계속 내리다보면 영상이 계속 추가로 로드되고

 

계속 더 내리다보면 추가로드 라는 버튼이 활성화되며 이를 클릭하면 영상이 또 추가로 로드가 되는 것을 확인할 수 있습니다.

 

 

 

그럼 이 추가로드 버튼까지 클릭해가며, 동영상이 더 이상 추가되지 않을 때까지 스크롤을 내려보겠습니다.

 

스크롤을 충분히 내려 추가로드 버튼이 보일때까지 내려줍니다.

 

F12 개발자도구를 키고, 추가로드 버튼을 찾아보시면 div class의 아이디가 feed-main-what_to_watch 이고,

 

그 아래 button이 보이는 것을 확인 할 수 있습니다.

 

스크롤을 내리며, 이것을 클릭해 주도록 만들어 스크롤을 더 이상 영상이 로드 안될 때 까지 내려보겠습니다.

 

1
2
3
4
5
6
7
8
9
10
num_of_pagedowns = 50
 
while num_of_pagedowns:
    body.send_keys(Keys.PAGE_DOWN)
    time.sleep(0.3)
    num_of_pagedowns -= 1
    try:
        driver.find_element_by_xpath("""//*[@id="feed-main-what_to_watch"]/button""").click()
    except:
        None
cs

 

위와 같이, from selenium.webdriver.common.keys import Keys를 추가해줌으로써

 

HTML body 영역에다가 pagedown키를 누르게 함으로써 페이지를 내릴 수 있습니다.

 

이렇게 0.3초 간격으로 50번을 내려주면 보통 끝까지 도달합니다.

 

다음으로는 추가로드 버튼이 보이면 클릭되는 부분을 try구문에 적어주었고, 발견되지 않으면 아무것도 동작하지 않도록 했습니다.

 

이렇게 페이지 끝에 도달하면,

 

여기까지 로드 된 HTML을 가져오고 이를 BeautifulSoup으로 분석하겠습니다.

 

1
2
3
html = driver.page_source
soup = BeautifulSoup(html, 'lxml')
titles = soup.find_all('h3')
cs

 

위와 같이 webdriver가 연 url의 html은 page_source를 통해 가져올 수 있고,

 

이를 BeautifulSoup으로 분석합니다. 제목이 h3 태그값에 존재하기에 그 제목값을 모두 찾아줍니다.

 

그리고,

 

1
2
3
4
for title in titles:
    print (title.get_text())
    
driver.close()
cs

 

출력해주면 모든 제목을 가져올 수 있게 됩니다. 마지막에는 close()를 통해 webdriver을 닫아줍니다.

 

 

페이지의 출력 결과

 

1
2
3
4
5
6
7
8
9
10
11
12
7개 지옥, 7번의 재판 [신과 함께: 죄와 벌]
한국인에게 인종차별한 미국인 역관광
국내 언론에서는 다루지 않은 문재인 대통령 혼밥 아무도 몰랐던 그 진실 이야기 감동 사연
피자집 의자에 앉기만 하면~ 고양이가 무릎위로 온다? 고양이를 부르는 요술 의자
[유병재 라이브] 문학의 밤 유행어 짓기 선수권 (with 유규선 문상훈)
[예능연구소 직캠] 트와이스 하트 쉐이커 @쇼!음악중심_20171216 HEART SHAKER TWICE in 4K
리니지m 똘끼 리니지참 피곤해...
롤은 이기려고 하는거 아닙니다. 상대 빡치라고 하는겁니다.
우주하마 배틀그라운드 ♥ LIVE
[ 인피쉰 LIVE ] ( 2017-12-18 월요일 생방송) 안녕하세요! 빨무 스타 스타크래프트 팀플레이 Shin Starcraft
LOL 롤 브실골 미드/원딜 1위. 저격 환영
...(중략)...
cs

위 이미지에서 안보이는 제목은 > 버튼을 클릭하니 동영상이 존재하더군요.

 

이렇게 웹 페이지에서 스크롤을 내린 후 크롤링을 해오는 코드를 작성해보았습니다.

 

아래는 전체 코드 입니다.

 

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
26
27
28
29
30
31
32
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import time
 
driver = webdriver.Chrome()
 
driver.get('https://www.youtube.com/')
 
time.sleep(2)
 
body = driver.find_element_by_tag_name("body")
 
num_of_pagedowns = 50
 
while num_of_pagedowns:
    body.send_keys(Keys.PAGE_DOWN)
    time.sleep(0.3)
    num_of_pagedowns -= 1
    try:
        driver.find_element_by_xpath("""//*[@id="feed-main-what_to_watch"]/button""").click()
    except:
        None
 
html = driver.page_source
soup = BeautifulSoup(html, 'lxml')
titles = soup.find_all('h3')
 
for title in titles:
    print (title.get_text())
 
driver.close()
cs

'크롤링' 카테고리의 다른 글

네이버 영화순위 크롤링  (1) 2017.12.17

★ 아직 많이 부족합니다. 댓글을 통한 가르침 환영입니다. ★

 

이번에는 Python을 활용하여 네이버 영화순위를 크롤링해오도록 하겠습니다.

 

제가 분석할 URL은 http://movie.naver.com/movie/sdb/rank/rmovie.nhn 입니다.

 

HTML을 가져와 분석하기 위해, BeautifulSoup4를 활용하겠습니다.

 

 

들어가기 앞서, 제 개발환경은

 

[ Windows 10 64-bit, Python 3.5.4, IDE : Pycharm ]

 

[Anaconda3]를 활용하고 있습니다.

 

자, 그럼

 

가장 먼저, BeautifulSoup4을 설치해보도록 하죠.

 

pip install BeautifulSoup4 

 

 

다음은, URL의 정보를 가져오기 위해 코드를 작성해봅시다.

 

BeautifulSoup을 활용할 경우 코드가 정말 간단히 작성됩니다.

 

1
2
from bs4 import BeautifulSoup
import urllib.request
cs

 

이렇게 두 라이브러리를 import 해줍니다.

 

1
html = urllib.request.urlopen('http://movie.naver.com/movie/sdb/rank/rmovie.nhn')
cs

 

이렇게 URL을 통해 가져온 html 데이터를 BeautifulSoup4를 활용하여 분석하도록 하겠습니다.

 

1
soup = BeautifulSoup(html, 'lxml')
cs

 

여기서, 혹시 에러가 발생한다면

 

pip install lxml 

 

을 설치해주도록 합니다. 다음,

 

1
print (soup)
cs

 

을 통해 출력을 해보면, 네이버 영화 순위 사이트에 해당하는 HTML 데이터가 출력되는 것을 확인할 수 있습니다.

 

사이트 진입 후, F12 개발자도구를 열어 확인할 수 있는 데이터입니다.


그럼 이 URL을 본격적으로 분석해보도록 하겠습니다.

 

1
titles = soup.find_all('td''title')
cs

 

먼저, 각 순위에 해당하는 모든 영화 정보를 titles에 담아옵니다.

 

이렇게 코드를 작성한 이유는,

 

 

 

F12 개발자도구를 확인하여 2017년 12월 17일 기준 1등인 영화 '강철비'라는 텍스트가 위치한 곳이

 

td -> div -> a href 의 텍스트로 위치해있기 때문에, td 클래스의 이름은 title인 것을 가져오도록 작성하였습니다.

 

1
2
3
4
5
6
7
8
9
10
11
<td class="title">
    <div class="tit3">
        <a href="/movie/bi/mi/basic.nhn?code=155665" title="강철비">강철비</a>
    </div>
 
    </td><td class="title">
        <div class="tit3">
            <a href="/movie/bi/mi/basic.nhn?code=160399" title="기억의 밤">기억의 밤</a>
    </div>
 
...(중략)...
cs

 

이렇게 가져오며,

 

여기서

 

<a href="/movie/bi/mi/basic.nhn?code=155665" title="강철비">강철비</a>

 

위 줄의 빨간색의 강철비 텍스트를 가져오기 위해서는

 

1
print (titles[0].find('a').text)
cs

 

와 같이 작성하여 가져올 수 있습니다.

 

그렇다면, 50개의 모든 영화순위를 가져오기 위해 반복문을 작성해보겠습니다.

 

1
2
3
4
5
rank = 1
 
for title in titles:
    print(str(rank) + "위 : " + title.find('a').text)
    rank += 1
cs

 

순위를 명시해주기 위한 rank 변수도 만들어 위와 같이 반복문을 작성하면

 

1
2
3
4
5
6
7
8
9
1위 : 강철비
2위 : 기억의 밤
3위 : 꾼
4위 : 어쌔신: 더 비기닝
5위 : 스타워즈: 라스트 제다이
6위 : 메리와 마녀의 꽃
7위 : 신과함께-죄와 벌
8위 : 오리엔트 특급 살인
...(중략)...
cs

 

이와 같이 2017년 12월 17일 기준의 영화 순위가 출력되게 됩니다.

 

여기서 멈추지 않고 추가로, 각 영화의 링크 주소도 가져와보도록 하겠습니다.

 

위의 영화 이름을 가져왔던 코드에 한 줄을 추가하여

 

1
2
print (titles[0].find('a').text)
print (titles[0].find('a')['href'])
cs

 

다음과 같이 만들어,

 

<a href="/movie/bi/mi/basic.nhn?code=155665" title="강철비">강철비</a>

 

위의 파란색으로 표시된 링크까지 가져올 수 있게 됩니다.

 

1
2
강철비
/movie/bi/mi/basic.nhn?code=155665
cs

 

링크를 완전하게 만들기 위해,

 

1
print ('http://movie.naver.com/' + titles[0].find('a')['href'])
cs

 

다음과 같이 수정하여,

 

1
http://movie.naver.com//movie/bi/mi/basic.nhn?code=155665
cs

 

위와 같은 완전한 링크를 얻어냅니다.

 

그럼 이제 영화 순위와 함께, 영화의 링크도 가져오는 전체 코드를 작성해보도록 하겠습니다.

 

1
2
3
4
5
6
7
8
9
10
11
from bs4 import BeautifulSoup
import urllib.request
 
html = urllib.request.urlopen('http://movie.naver.com/movie/sdb/rank/rmovie.nhn')
soup = BeautifulSoup(html, 'lxml')
titles = soup.find_all('td''title')
front_url = 'http://movie.naver.com/'
rank = 1
for title in titles:
    print(str(rank) + " : " + title.find('a').text + ' / link : ' + front_url + title.find('a')['href'])
    rank += 1
cs

 

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
1위 : 강철비 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=155665
2위 : 기억의 밤 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=160399
3위 : 꾼 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=152385
4위 : 어쌔신: 더 비기닝 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=100205
5위 : 스타워즈: 라스트 제다이 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=125488
6위 : 메리와 마녀의 꽃 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=159037
7위 : 신과함께-죄와 벌 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=85579
8위 : 오리엔트 특급 살인 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=154272
9위 : 반드시 잡는다 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=155411
10위 : 이프 온리 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=39440
11위 : 뽀로로 극장판 공룡섬 대모험 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=169349
12위 : 덩케르크 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=146480
...(중략)...
41위 : 무서운 꿈 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=170236
42위 : 역모 - 반란의 시대 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=142210
43위 : 정글 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=158623
44위 : 미옥 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=142317
45위 : 킹스맨: 골든 서클 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=149747
46위 : 극장판 포켓몬스터 너로 정했다! / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=165722
47위 : 쥬라기 월드: 폴른 킹덤 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=154285
48위 : 1급기밀 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=149504
49위 : 러브 액츄얼리 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=36843
50위 : 원더 / link : http://movie.naver.com//movie/bi/mi/basic.nhn?code=151196
 
2017-12-17
cs

 

이렇게 BeautifulSoup을 통해 몇 줄 안되는 코드로 영화 순위를 가져오는 코드를 작성해보았습니다.

'크롤링' 카테고리의 다른 글

Selenium(셀레니움)을 활용한 크롤링  (2) 2017.12.18

+ Recent posts