通过单击按钮刮取网页并导航

时间:2013-08-10 09:40:33

标签: node.js web-scraping phantomjs jsdom zombie.js

我想在服务器端执行以下操作:

1)抓一个网页
2)模拟该页面上的单击,然后导航到新页面。
3)刮新页面
4)模拟新页面上的一些按钮点击
5)通过json或其他东西将数据发送回客户端

我正在考虑将它与Node.js一起使用。

但我对应该使用哪个模块感到困惑 a)僵尸
b)Node.io
c)Phantomjs
d)JSDOM
e)其他任何事情

我已经安装了node,io但是无法通过命令提示符运行它。

PS:我在Windows 2008服务器上工作

3 个答案:

答案 0 :(得分:38)

Zombie.js和Node.io在JSDOM上运行,因此您可以使用JSDOM(或任何等效的包装器),无头浏览器(PhantomJS,SlimerJS)或Cheerio。

  • JSDOM相当慢,因为它必须在Node.js中重新创建DOM和CSSOM。
  • PhantomJS / SlimerJS是合适的无头浏览器,因此性能还可以,而且非常可靠。
  • Cheerio是JSDOM的轻量级替代品。它不会在Node.js中重新创建整个页面(它只是下载并解析DOM - 不执行javascript)。因此,您无法真正点击按钮/链接,但抓取网页的速度非常快。

鉴于您的要求,我可能会选择像无头浏览器这样的东西。特别是,我选择CasperJS,因为它有一个漂亮而富有表现力的API,它快速可靠(它不需要像JSDOM一样重新解析如何解析和渲染dom或css)和与按钮和链接等元素进行交互非常容易。

您在CasperJS中的工作流程应该或多或少看起来像这样:

casper.start();

casper
  .then(function(){
    console.log("Start:");
  })
  .thenOpen("https://www.domain.com/page1")
  .then(function(){
    // scrape something
    this.echo(this.getHTML('h1#foobar'));
  })
  .thenClick("#button1")
  .then(function(){
    // scrape something else
    this.echo(this.getHTML('h2#foobar'));
  })
  .thenClick("#button2")
  thenOpen("http://myserver.com", {
    method: "post",
    data: {
        my: 'data',
    }
  }, function() {
      this.echo("data sent back to the server")
  });

casper.run(); 

答案 1 :(得分:2)

您列出的模块执行以下操作:

  • Phantomjs / Zombie - 模拟浏览器(无头 - 实际上没有显示任何内容)。可用于刮静态或动态。或者测试你的html页面。
  • Node.io/jsdom - webscraping:从页面提取数据(静态)。

根据您的要求,您可以使用幻像或僵尸。

答案 2 :(得分:1)

简短回答(于2019年):使用操纵up

如果您需要完整(无头)浏览器,请使用puppeteer而不是PhantomJS,因为它提供了带有丰富API的最新Chromium浏览器,可以自动执行所有浏览器的抓取和抓取任务。如果只想解析HTML文档(而不在页面内执行JavaScript),则应签出jsdomcheerio

说明

诸如jsdom(或cheerio)之类的工具允许它通过解析从HTML文档中提取信息。只要该网站不包含JavaScript,这便是快速且有效的方法。从基于JavaScript的网站提取信息将非常困难,甚至不可能。例如,jsdom能够执行脚本,但是可以在Node.js环境中的沙箱中运行脚本,这可能非常危险,甚至可能导致应用程序崩溃。引用docs

  

但是,这在处理不受信任的内容时也非常危险。

因此,要可靠地爬网更复杂的网站,您需要一个实际的浏览器。多年来,用于此任务的最受欢迎的解决方案是 PhantomJS 。但是在2018年,PhantomJS的开发是offically suspended。值得庆幸的是,自2017年4月以来,Google Chrome团队就可以无头运行Chrome浏览器(announcement)。 这样就可以使用具有完整JavaScript支持的最新浏览器来抓取网站。

要控制浏览器,puppeteer库(也由Google开发人员维护)提供了丰富的API,供在Node.js环境中使用。

代码示例

下面的几行显示了一个简单的示例。它使用Promises和async / await语法来执行许多任务。首先,启动浏览器(puppeteer.launch)并打开URL page.goto。 之后,使用page.evaluatepage.click之类的函数来提取信息并在页面上执行操作。最后,浏览器关闭(browser.close)。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.goto('https://example.com');

  // example: get innerHTML of an element
  const someContent = await page.$eval('#selector', el => el.innerHTML);

  // Use Promise.all to wait for two actions (navigation and click)
  await Promise.all([
    page.waitForNavigation(), // wait for navigation to happen
    page.click('a.some-link'), // click link to cause navigation
  ]);

  // another example, this time using the evaluate function to return innerText of body
  const moreContent = await page.evaluate(() => document.body.innerText);

  // click another button
  await page.click('#button');

  // close brower when we are done
  await browser.close();
})();