更新
我在页面中找到了一个标签'base',我无法运行jQuery。如果网站包含该标签,jsdom就无法运行。虽然我不知道为什么。
<base href="http://bbs.18183.com/" />
为了验证这一点,我创建了一个全新的HTML文件并放入内部,然后jsdom失败。
我目前正在玩Node.js,在阅读How to Scrape Web Pages with Node.js and jQuery之后,我决定为我创建一个。
所以我安装了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树。即使我将$更改为其他名称,它仍然无效。
有人对此有所了解吗?
答案 0 :(得分:2)
我看到这里发生了什么。这不是一个错误,但我可以看到它出乎意料的地方。这是正在发生的事情:
scripts: ['jquery.js']
转换为“插入<script src="jquery.js">
”。当jsdom看到<script src="jquery.js">
时,它会尝试相对于当前文档的网址加载jquery.js
。
在没有<base>
标记的文档中,当您使用HTML片段字符串而不是通过URL显式加载它们时,文档URL将设置为与您当前脚本对应的file://
URL。我打赌jquery.js
就在你当前的脚本旁边,所以效果很好:<script src="jquery.js">
解决得很好。
但是在带有<base>
标记的文档中,文档的URL设置为该基础。因此,在这种情况下,<script src="jquery.js">
会转换为加载<base href="http://localhost/jquery.js">
,我敢打赌,在localhost端口80上运行的服务器上没有jquery.js
。所以这会失败。
修复是更明确的。我建议像
这样的东西var path = require("path");
jsdom.env({
html: myHTML,
scripts: [path.resolve(__dirname, "jquery.js")],
done: function (errors, window) {
}
});
请注意,如果您检查了errors
变量,则可能会看到一个错误,为您提供线索。您似乎没有任何此类错误处理代码。