为什么“基地”标记是防止jsdom.env工作?
更新:
我发现页面中使用的标记“base”,我没有运行jQuery。如果网站包含该标记,jsdom将不起作用。 虽然我不知道为什么。
<base href="http://bbs.18183.com/" />
为了validation这一点,我创build了一个全新的HTML文件,并放入一个里面,jsdom然后失败。
我目前在玩Node.js,在阅读了如何使用Node.js和jQuery来抓取网页之后,我决定为我创build一个。
所以我安装了express,jsdom和很多东西,发现抓取网页真的很方便。 但后来我发现了一个奇怪的情况,某个特定的页面不能被抓取,而是提示错误如下:
var title = $('title').text(); ^ TypeError: undefined is not a function at H:\animalwar\personal\node\getter\app.js:82:23 at exports.env.exports.jsdom.env.scriptComplete (H:\animalwar\personal\node\ getter\node_modules\jsdom\lib\jsdom.js:207:39) at process.startup.processNextTick.process._tickCallback (node.js:244:9)
这是我的代码:
request({ url:'http://bbs.18183.com/'}, function (err, response, body) { if(err && response.statusCode !== 200){ console.log('Connection Failure! Fuck GFW'); res.end('Connection Failure! Fuck GFW'); return; } jsdom.env({ html: body, scripts: ['jquery.js'] }, function(err, window){ //Use jQuery just as in a regular HTML page var $ = window.jQuery; var title = $('title').text(); console.log('SUCCESSFULLY GOT: ', title ); res.end(title); } ); });
网站“ http://bbs.18183.com/ ”在这种情况下不起作用,但许多其他网站正在工作。 例如,将其更改为“ http://www.18183.com/ ”,正在工作。
我想这是由于“$”的定义冲突,但后来我意识到,与jsdom.env页面只是一个DOM树。 即使我改变了其他名字,它仍然无法正常工作。
有人对这个有了解吗?
我看到这里发生了什么。 这不是一个错误,但我可以看到它的意外。 这是发生了什么事情:
scripts: ['jquery.js']
翻译成“插入<script src="jquery.js">
”。 当jsdom看到<script src="jquery.js">
,它会尝试加载相对于当前文档的URL的jquery.js
。
在没有<base>
标签的文档中,当使用HTML片段string而不是通过URL显式地加载它们时,文档URL被设置为与当前脚本对应的file://
URL。 我敢打赌, jquery.js
就在你的当前脚本的旁边,所以这很好用: <script src="jquery.js">
解决就好了。
但在具有<base>
标签的文档中,文档的URL被设置为该基础。 因此,在这种情况下, <script src="jquery.js">
转换为加载<base href="http://localhost/jquery.js">
,我打赌你没有在服务器上提供jquery.js
在本地主机端口80上运行。所以这失败了。
修复是更加明确的。 我会build议类似的
var path = require("path"); jsdom.env({ html: myHTML, scripts: [path.resolve(__dirname, "jquery.js")], done: function (errors, window) { } });
请注意,如果你检查了你的errors
variables,你可能会看到一个错误,给你一个线索。 你似乎没有任何这样的error handling代码。