【问题标题】:Scrape a webpage and navigate by clicking buttons抓取网页并通过单击按钮进行导航
【发布时间】:2013-08-12 05:00:46
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

    简答(2019 年):使用 puppeteer

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

    说明

    jsdom(或cheerio)这样的工具允许它通过解析从HTML文档中提取信息。只要网站不包含 JavaScript,这速度很快并且效果很好。从基于 JavaScript 的网站中提取信息将非常困难,甚至是不可能的。例如,jsdom 能够执行脚本,但是在您的 Node.js 环境中的沙箱中运行它们,这可能非常危险并且可能使您的应用程序崩溃。引用docs

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

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

    为了控制浏览器,同样由 Google 开发人员维护的库 puppeteer 提供了丰富的 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();
    })();
    

    【讨论】:

    • 好建议!由于 PhantomJS 存在漏洞,这是一个直接在 Node 中运行的开箱即用解决方案,我现在很喜欢。
    【解决方案2】:

    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(); 
    

    【讨论】:

    • 还有你对使用僵尸的看法'
    • 根据我的经验,Zombie 不如 PhantomJS 或 CasperJS 可靠。有时流程会被非常奇怪的故障打断,我似乎无法理解何时使用按钮、点击、链接等来导航页面。然而,让 Node 运行抓取而不是外部进程是很好的。我想这真的取决于你的应用程序。如果您可以解决外部服务正在执行抓取的事实,请使用无头浏览器。
    • 谢谢! zombiejs/spookyjs 也能模拟物理按键吗?
    【解决方案3】:

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

    • Phantomjs/Zombie - 模拟浏览器(无头 - 实际上没有显示)。可用于静态或动态抓取。或测试您的 html 页面。
    • Node.io/jsdom - 网页抓取:从页面中提取数据(静态)。

    看你的要求,你可以使用幻影或僵尸。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 2020-11-09
      • 1970-01-01
      • 1970-01-01
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多