Node.js:请求页面并允许页面在构build之前构build

我已经看到了一些这样的答案,将askee引用到其他库(如phantom.js),但是我在这里想知道是否完全可以在node.js中做到这一点?

考虑到我的代码如下。 它使用request请求一个网页,然后使用cheerio探索dom来cheerio数据页面。 它的工作完美无缺,如果一切按计划进行,我相信它会输出一个我想像中的文件。

问题是, 我正在请求的页面 ,以build立表格即时查看asynchronous使用ajax或jsonp,我不完全确定.jsp页面如何工作。
所以在这里,我正试图find一种方法来“加载”这个数据,然后再加载我的新文件。

 var cheerio = require('cheerio'), request = require('request'), fs = require('fs'); // Go to the page in question request({ method: 'GET', url: 'http://www1.chineseshipping.com.cn/en/indices/cbcfinew.jsp' }, function(err, response, body) { if (err) return console.error(err); // Tell Cherrio to load the HTML $ = cheerio.load(body); // Create an empty object to write to the file later var toSort = {} // Itterate over DOM and fill the toSort object $('#emb table td.list_right').each(function() { var row = $(this).parent(); toSort[$(this).text()] = { [$("#lastdate").text()]: $(row).find(".idx1").html(), [$("#currdate").text()]: $(row).find(".idx2").html() } }); //Write/overwrite a new file var stream = fs.createWriteStream("/tmp/shipping.txt"); var toWrite = ""; stream.once('open', function(fd) { toWrite += "{\r\n" for(i in toSort){ toWrite += "\t" + i + ": { \r\n"; for(j in toSort[i]){ toWrite += "\t\t" + j + ":" + toSort[i][j] + ",\r\n"; } toWrite += "\t" + "}, \r\n"; } toWrite += "}" stream.write(toWrite) stream.end(); }); }); 

预期的结果是一个信息格式为JSON对象的文本文件。

它应该看起来像这样的不同实例

 "QINHUANGDAO - GUANGZHOU (50,000-60,000DWT)": { "2016-09-29": 26.7, "2016-09-30": 26.8, }, 

但是由于名称是唯一不加载asynchronous,(date和值是asynchronous)我得到一个搞砸的对象。

我试过其实只是在代码中的各个地方设置setTimeout 。 脚本只会被开发者触动,如果脚本失败了几次,脚本可以多次运行脚本。 所以虽然不理想,但即使setTimeout(最多5秒)也足够了。

原来settimeouts不起作用。 我怀疑,一旦我请求了页面,当我收到页面的时候,我就会停留在页面的快照上,而实际上我并没有看到可以等待加载其dynamic内容的活动。

我想知道如何拦截软件包,但是我不太清楚HTTP是否知道从哪里开始。

setTimeout即使增加到一个小时也没有什么区别。 这里的问题是你正在对这个url提出请求: http : //www1.chineseshipping.com.cn/en/indices/cbcfinew.jsp

和他们的服务器返回的HTML和在这个HTML有js和css的import。 这是你的情况的结束,你只是有HTML,就是这样。 相反,浏览器知道如何使用和parsingHTML文档,所以它能够理解JavaScript脚本并执行/运行它们,这正是你的问题。 您的程序无法理解与HTML内容有关的内容。 你需要find或写一个能够运行JavaScript的刮板。 我刚刚在stackoverflow上发现了这个类似的问题: 用Python抓取JavaScript页面

那家伙build议https://github.com/niklasb/dryscrape ,似乎这个工具能够运行JavaScript。 它是用python写的。

您正试图抓取不包含您所需数据的原始页面。 当页面被加载时,浏览器评估它包含的JS代码,并且这个代码知道在哪里以及如何获取数据。

第一个select是评估相同的代码,就像PhantomJS那样。

另一个(你似乎对此感兴趣)是调查页面的networking活动,并了解你应该执行什么额外的请求来获取你需要的数据。 在你的情况下,这些是:

http://index.chineseshipping.com.cn/servlet/cbfiDailyGetContrast?SpecifiedDate=&jc=jsonp1475577615267&_=1475577619626

http://index.chineseshipping.com.cn/servlet/allGetCurrentComposites?date=Tue%20Oct%2004%202016%2013:40:20%20GMT+0300%20(MSK)&jc=jsonp1475577615268&_​​=1475577620325

在这两个请求中:

因此,在http://www1.chineseshipping.com.cn/en/indices/cbcfinew.jsp上删除表格模板,并执行两个额外的request您将能够将它们组合成您在浏览器中看到的相同的数据结构。