【问题标题】:node.js request a webpage with async scriptsnode.js 请求带有异步脚本的网页
【发布时间】:2016-01-22 20:31:36
【问题描述】:

我正在使用request 模块下载一个网页,该模块非常简单。

我的问题是我尝试下载的页面有一些异步脚本(具有 async 属性),并且没有从 http 请求返回的 html 文档下载它们。

我的问题是如何使用/不使用(最好使用)请求模块发出 http 请求,并且由于某些边缘情况,如上所述,没有例外地下载整个页面。

【问题讨论】:

  • 使用无头浏览器,也许
  • @mithril_knight 您好,感谢您的回复,请查看我对 chriskelly 帖子的评论。仍在寻找解决方案。 :)
  • 还在苦苦挣扎,如果有人能帮我找到解决方案,我将不胜感激

标签: javascript node.js request httprequest


【解决方案1】:

听起来您正在尝试使用 Javascript 进行网页抓取。

使用request 是一种非常基础的方法,它可能太低级并且对于您的需求来说很耗时。该主题相当广泛,但您应该研究更多专门构建的模块,例如cheerio、x-ray 和 nightmare。

x-ray x-ray 将让您以类似 jquery 的方式直接从页面中选择元素,而不是解析整个正文。

nightmare 提供了一个现代的无头浏览器,使您可以像手动使用浏览器一样输入输入。有了这个,您应该能够更好地处理导致您出现问题的 ajax 类型请求。

HTH,祝你好运!

【讨论】:

  • 你说得对,基本上我在爬网。我正在使用正则表达式数组在返回的文档中查找可能的 uri,因为使用 cherrio/jsdom/x-ray 等是不够的,因为 src/href 属性值中没有 uri。除了这个无头浏览器不会做得那么好,因为我想要实现的是存档和镜像网站(类似于 HTTrack)。我已经完成了大部分代码,我选择使用 request 来处理http 请求,但问题是,与在浏览器中打开网站不同,请求模块返回的文档不包含任何异步脚本
  • @Jorayen 正是这种情况发生在我身上,我不得不切换到 phantomjs,在那之前我用过cheerio,但和你一样,它没有加载异步脚本内容
【解决方案2】:

仅使用请求,您可以尝试以下方法来拉取异步脚本。

注意:我已经用一个非常基本的设置对此进行了测试,并且需要做一些工作来使其更加健壮。但是,它对我有用:

测试设置

为了设置测试,我创建了一个 html 文件,其中在正文中包含一个脚本,如下所示:<script src="abc.js" async></script>

然后创建临时服务器来启动它(httpster)

刮板

"use strict";

const request = require('request');

const options1 = { url: 'http://localhost:3333/' }

// hard coded script name for test purposes
const options2 = { url: 'http://localhost:3333/abc.js' }

let htmlData  // store html page here

request.get(options1)
    .on('response', resp => resp.on('data', d => htmlData += d))
    .on('end', () => {
        let scripts; // store scripts here

        // htmlData contains webpage
        // Use xml parser to find all script tags with async tags
        // and their base urls
        // NOT DONE FOR THIS EXAMPLE

        request.get(options2)
            .on('response', resp => resp.on('data', d => scripts += d))
            .on('end', () => {
                let allData = htmlData.toString() + scripts.toString();
                console.log(allData);
            })
           .on('error', err => console.log(err))
    })
    .on('error', err => console.log(err))

这个基本示例有效。您将需要在页面上找到所有 js 脚本并提取我在这里没有完成的 url 部分。

【讨论】:

  • 问题是在'end'事件上完成第一个请求后, htmlData 中不包含任何异步脚本,所以我真的找不到那些异步脚本标签,即我的问题
猜你喜欢
  • 2012-02-25
  • 2013-09-13
  • 2013-10-23
  • 2016-10-05
  • 1970-01-01
  • 2019-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多