WebdriverIO 를 사용한 웹 데이터 수집

웹 상의 데이터 수집 시 크롬, 사파리 등의 웹 브라우저를 WebdriverIO를 통해 제어하여 수집하는 방법을 소개한다.


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를 넘겨주면서 처리하면 정리가 가능하다.

 

댓글 남기기