웹 상의 데이터 수집 시 크롬, 사파리 등의 웹 브라우저를 WebdriverIO를 통해 제어하여 수집하는 방법을 소개한다.
- 사전지식
- javascript
- jQuery
- Node.js
- Reference
Dependencies
- Selenium Standalone 설치
$ npm install -g selenium-standalone $ selenium-standalone install
- Nodejs 라이브러리 설치
$ npm install cheerio webdriverio
- 웹 드라이버
- 크롬, 파이어폭스는 플러그인 없이 기본으로 제공되지만, 사파리나 인터넷 익스플로러를 제어하기 위해서는 별도의 플러그인을 설치해야한다. (아래 링크)
- http://selenium-release.storage.googleapis.com/2.45
Usage
아래의 코드는 webdriverio를 통해 네이버에서 nodejs를 검색하고 뉴스탭을 선택한 후 뉴스 기사의 제목과 링크를 가져오는 작업을 진행한다.
- Selenium Standalone 실행
$ selenium-standalone start
- index.js
var webdriverio = require('webdriverio'); var cheerio = require('cheerio'); var options = {desiredCapabilities: {browserName: 'chrome'}}; var client = webdriverio.remote(options); client = client.init(); client .url('http://www.naver.com') .setValue('#query', 'nodejs') .click('#search_btn') .getHTML('body') .then(function (html) { var $ = cheerio.load(html); var selector = ''; $('.lnb_menu > .base li > a > span').each(function () { if ($(this).text().trim() == '뉴스') { var css = $(this).parent().parent().attr('class'); css = css.trim().replace(/ /gim, '.'); selector = '.lnb_menu > .base .' + css + ' a'; } }); client .click(selector) .getHTML('body') .then(function (html) { var $ = cheerio.load(html); var list = []; $('.news.mynews.section dl dt a').each(function () { var title = $(this).text().trim(); var href = $(this).attr('href'); list.push({title: title, href: href}); }); console.log(list); }) .end(); });
- 소스코드 실행
node index.js
- 결과
[ { title: '신간 | Node.js와 fluentd를 활용해서 배우는 오픈소스 몽고DB', href: 'http://www.ciokorea.com/news/29028' }, { title: 'MS는 왜 리눅스를 껴안았을까', href: 'http://www.it.co.kr/news/article.html?no=2818642' }, { title: '오라클 클라우드가 기업 데이터센터 품으로?', href: 'http://www.inews24.com/php/news_view.php?g_serial=954925&g_menu=020200&rrf=nv' }, { title: '[4.26 버그리포트] CVE-2016-1202 外', href: 'http://www.boannews.com/media/view.asp?idx=50422&kind=5' }, { title: 'Node.js개발자를 위한 테크컨퍼런스 … 플레이노드 2015 개최', href: 'http://platum.kr/archives/48203' }, { title: '[NDC 2016] "\'파판11 리부트\' 실시간 모바일 MMORPG로 만들고 있습니다"', href: 'http://news.donga.com/3/all/20160427/77808821/1' }, { title: '11줄의 코드, 인터넷을 패닉에 빠뜨리다', href: 'http://www.bloter.net/archives/253447' }, { title: '“개발자여, 봇을 만들자” 마이크로소프트, 봇 프레임워크 발표 : 빌드 컨퍼...', href: 'http://www.itworld.co.kr/news/98621' }, { title: '새로운 Node.js, 가장 좋은 시기에 io.js와 통합', href: 'http://www.itworld.co.kr/news/94085' }, { title: '한국전자출판협회, 전자책 전문 교육', href: 'http://www.sjbnews.com/news/articleView.html?idxno=521481' } ]
소스코드 설명 및 이슈
- options
- browserName에 브라우져의 이름을 입력하면 해당 브라우져로 실행된다.기본적으로 플러그인 설치없이 크롬과 파이어폭스를 selenium-standalone에서 제공하고 있다. 옵션의 변수를 통해 브라우저의 버전 등을 선택하여 실행도 가능하다. 자세한 내용은 http://webdriver.io/guide/getstarted/configuration.html 링크를 참조.
- client 객체
- 주요 함수
- setValue 함수: css 셀렉터를 통해 선택된 노드에 value 속성에 값을 넣어줌
- click 함수: css 셀렉터를 통해 선택된 노드를 클릭해줌
- getHTML 함수: css 셀렉터를 통해 선택된 노드의 HTML 태그를 불러옴
- then 함수: html 내용을 콜백함
- 이슈
- client 객체는 click 이후에 팩토리 패턴을 사용하여 추가 작업을 할 경우, 클릭 시점 이전인 현재 페이지에서 추가 작업이 진행된다. 위의 코드에서는 then 함수 에서 작업을 수행한 후 추가 작업을 수행하였다.
- 작업 수가 많아지면 콜백으로 인해 코드가 지져분해지는데, async 라이브러리를 활용하여 client를 넘겨주면서 처리하면 정리가 가능하다.
- 주요 함수