in JavaScript

爬虫的终极形态:nightmare

nightmare 是一个基于 electron 的自动化库(意思是说它自带浏览器),用于实现爬虫或自动化测试。相较于传统的爬虫框架(scrapy/pyspider),或者dom操作库(cheerio/jsdom),或者基于浏览器的自动化框架(selenium/phantomjs),他的优势在于提供了一个简洁有效 的编程模型。

来看官网给出的一个对比场景:

同样是实现一个向yahoo自动提交关键词并搜索的功能

1. PhantomJS实现

2. nightmare实现

怎么玩

安装

涉及到下载并编译一个electron,你国网速下需耐心等待

配置 options

实例化

交互用的API

简单介绍几个:

  • .goto(url[, headers]) 跳转到url
  • .viewport(width, height) 浏览器窗口大小
  • .wait(selector) 等待某个dom元素出现
  • .click(selector) 点击某个dom元素
  • .type(selector[, text]) 在某个dom元素中输入
  • .inject(type, file) 在页面上挂载 js/css 文件内容
  • .evaluate(fn[, arg1, arg2,...]) 在客户端注入JS脚本并执行,从而实现electron模型下的C/S互动及数据交换
  • ……

自动登录并轮询的例子

有那么一个网站(比如叫chagang.site),在我登录进去后,会不定时的查岗,需要点击一个按钮以证明没有离线,怎么用nightmare实现自动挂机呢?

大概分这么几步走:

  1. 先跳转到该网站
  2. 模拟输入帐号信息后点击submit
  3. 登录后等待主界面加载出现
  4. 在客户端起一个定时器,2秒一次轮询那个查岗按钮,发现就模拟点击

好像也没有多难 🙂

小结

本文只涉及到API中的一小部分,宝贝都在文档里。用 nightmare,就是希望借助这种简洁模型的梳理,相对愉悦的实现自动化交互(至于标题,终归是意义过剩的产物,请忽略他的招摇。

打赏作者
您的支持将激励我继续创作!

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

Write a Comment

Comment

14 Comments

  1. nightmare
    .goto(url1)
    .cookies.get()
    .then(function(cookies) {
    ……
    })
    .goto(url2)

    求解:
    goto(url2) 为什么 执行不了
    如何才能继续执行goto(url2)

  2. 请问一下我按照你自动登录并轮询的例子代码,为什么evaluate里面的循环点击的代码好像没有运行
    index.html

    title

    window.onload=function () {
    var username=document.querySelector(‘#username’)
    var password=document.querySelector(‘#password’)
    var submit=document.querySelector(‘#submit’)
    submit.onclick=function () {
    if(username.value===’username’&& password.value===’123456′){
    window.location.href=’/main.html’
    }
    }
    }

    main.html

    title

    #inspector{
    display: block;
    }

    防止挂机按钮

    window.onload=function () {
    var inspector=document.querySelector(‘#inspector’);
    inspector.onclick=function () {
    this.style.display=’none’;
    setTimeout(function () {
    inspector.style.display=’block’;
    },2000)
    }
    }

    test.js
    let Nightmare = require(‘nightmare’)
    let nightmare = new Nightmare({
    show: true,
    openDevTools: {
    mode: ‘detach’
    },
    })
    nightmare
    .goto(‘http://localhost:4001/’)
    .viewport(1024, 768)
    .wait(1000)
    .type(‘#username’, ‘username’)
    .type(‘#password’, ‘123456’)
    .click(‘#submit’)
    .wait(1000)
    .wait(‘#mainContent’)
    .evaluate(() => {
    /* eslint-disable */
    function handle() {
    // 一个叫inspector的button
    var inspector = document.querySelector(‘#inspector’);
    if (inspector && inspector.style.display === ‘block’) {
    inspector.click();
    }
    }

    setInterval(handle, 1000);
    /* eslint-enable */
    })
    .evaluate(() => document.title)
    .then(title => console.log(${title} => 加载完成))
    .catch(err => console.error(err))