Mediteam.us 개발 – Python & Selenium을 이용한 구글검색 크롤링

‘관련글 검색’ 기능을 넣기 위한 시행착오 끝에 마지막으로 생각해낸 방식이 바로 사이트 내부의 구글 검색엔진을 이용하는 방법이었다. 핵심 키워드를 구하고, 그것을 검색창에 넣어 값을 가져오면 쉽게 가능할 것 같았다. 그리고 주기적으로 전체를 갱신해준다면, 그 값도 점점 최신이 될 것이라고 판단.

이를 위해 필요한 라이브러리가 바로 Selenium 이라는 것이다. 이전 포스팅에서도 소개했었지만,

이 책을 슥 읽어보면 어떤 기능을 구현해낼 수 있겠구나 감이 잘 온다.

그럼 왜 이런 번거로운 방식을 사용해야하느냐? 하면 바로, 우리가 바로 받을 수 있는 페이지 소스(HTML)은 우리가 원하는 결과물이 아니기 때문이다.

아래의 메디팀 사이트에 있는 구글 검색엔진을 이용할 경우 나오는 결과값이다. 그러나 실제 이 페이지는 달랑 몇줄의 자바스크립스로 쓰여진다.

아래와 같다.

즉, 우리가 원하는 것은 페이지의 기본 소스(HTML)값이 아니라, 실제로 저 페이지가 읽어진 다음 들어오는 진짜 결과이기 때문에, 셀레니움이 필요하게 된다.

셀레니움은 일종의 껍데기이고, 실제로 그 안에서 구동하는 드라이브가 필요하다. 크롬, 파이어폭스, PhantomJS 등이 있고, 나는 chromedriver를 사용하였다. 이유는 특별히 없었다.

크롬드라이버 최신버전을 받아 같은 폴더에 넣어준다. (https://sites.google.com/a/chromium.org/chromedriver/downloads)

깃헙 소스는 조금 바꿔서 올려서 동일한 결과가 나오진 않는다.

첫번째 예제 먼저 설명하면,

Github : https://github.com/junn279/python_examples/blob/master/selenium_basic.py

일단 주석을 무시하면,

10 : Chrome 드라이버를 불러온다.

11 : Chrome을 800×600으로 띄운다.

12 : ‘내용을 다운로드 받을때까지 5초까지 기다릴 것’ 임을 선언하다.

13 : 해당 주소를 연다.

14 : 받아진 소스를 받는다.

19 : 프로세스를 종료한다. (이것을 주석처리 안해놓으면, 작업이후에 창이 알아서 종료된다.) * 매우 중요한 한줄인데, 리눅스에서 이 처리를 안해놓으면 일종의 좀비 프로세스들이 계속 생성된다.

driver.quit은 프로세스 자체를 종료, driver.close는 창을 닫는 명령이다.

 

아래와 같이 페이지를 구성했고,

소스를 실행시키면 ‘자동화된 테스트 소프트웨어에 의해 제어되고 있습니다.‘ 라는 것이 출력되면서 원하는 주소가 오픈된다.

다시 소스로 돌아가면, 주석처리된 6, 7, 8, 22 번째 줄은 크롬을 직접 띄우지 않고 가상의 화면으로 돌릴 때 사용하는 코드이다. 이를 ‘Headless Chrome with Selenium’ 이라고 표현한다. 혹은 크롬드라이버를 띄울 때 –headless 옵션을 주는 방법이 있다. 이것은 두번째 소스에 포함되어 있다.

options = Options()
options.add_argument(‘–headless’)
options.add_argument(‘–no-sandbox’)

 

그러나 저 소스를 바로 리눅스 서버로 옮기면 시작부터 에러가 난다.

그것을 해결한 것이 두번째 깃헙 소스인데, 사실 –sandbox 옵션 하나만 더 넣음으로써 모든것이 끝나버렸다.

그 다음 발생한 문제는 바로 implicity wait에 관련된 문제다.

실제로 충분한 인터넷 속도가 보장된 데스크탑 환경에서는 5초정도 기다림으로서 대부분의 값을 다 받아낼 수 있으나, 리눅스에 넣었을 경우 이 속도가 상당히 느려지는 것을 확인할 수 있었다. 실제로 객체를 찾지못하고 중간에 exception이 생기는 것을 확인하기도 했다.

implicity wait이란 명시된 시간동안 일단 기다리고, 그 후에 object를 찾는 다는 의미로서, 만약 5초로 명시할 경우 최대 5초가 지나면 우리가 원하는 객체 여부와 상관없이 작업이 진행된다. 따라서 지정된 시간동안 갑작스런 인터넷 전송 지연으로 값이 받아지지 않는다면 에러가 발생할 수 있게 되는 것.

이를 해결하기 위한 방법으로 아래의 글들을 참조, Explicit wait를 사용하는 방법을 써야한다. (세번째 깃헙 코드) 이는 충분한 시간을 두면서 우리가 원하는 객체가 찾아질 경우 작업을 진행하는 방식이다.

http://toolsqa.com/selenium-webdriver/implicit-explicit-n-fluent-wait/

https://beomi.github.io/2017/10/29/HowToMakeWebCrawler-ImplicitWait-vs-ExplicitWait/

 

다음 편에서는 Explicit wait을 이용하여 세번째 소스로 실제 검색 결과를 받아오는 과정을 포스팅해보겠다.

 

Github source :

https://github.com/junn279/python_examples/blob/master/selenium_basic.py (기본, Implicitly Wait)

https://github.com/junn279/python_examples/blob/master/selenium_ubuntu.py (Ubuntu setting, Implicitly Wait)

https://github.com/junn279/python_examples/blob/master/selenium_ubuntu.py (Explicitly Wait)

 

References :

https://sites.google.com/a/chromium.org/chromedriver/downloads
https://christopher.su/2015/selenium-chromedriver-ubuntu/
https://beomi.github.io/2017/10/29/HowToMakeWebCrawler-ImplicitWait-vs-ExplicitWait/

0 Shares:
Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.