我试图在网站上抓取多个属性。我打算将它们加载到一个数组中,然后将该数组加载到我服务器上的数据库中的表中。
我尝试创建函数getInfo()
并将每个XPath属性加载到数组中(如果这是人们的建议,我可以加载到表中)。我在casper.repeat
步骤中将该函数调用了5次。我得到一个解析错误。我不知道这里出了什么问题,因为这是我设置数组来抓取URL并将它们添加到数组中的方法(我在手册中找到):Now let’s scrape Google!
非常感谢任何见解。
代码:
var links = [];
var utils = require('utils');
var casper = require('casper').create();
casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36');
function getInfo() {
var info = document.querySelectorAll(fetchText((x(//*[@id="body"]/div[1]/ul[1]/li[3]/span[1]/span[2]/a)))
+ ', ' + fetchText((x(//*[@id="body"]/div[1]/ul[1]/li[2]/h2/text()))
+ ', ' + fetchText((x()))
+ ', ' + fetchText((x(//*[@id="body"]/div[1]/ul[1]/li[4]/ul/li/span[2]/a)))
+ ', ' + fetchText((x(//*[@id="body"]/div[1]/ul[1]/li[2]/h2/span)))
+ ', ' + fetchText((x(//*[@id="body"]/div[1]/ul[1]/li[5]/div[2]/ul/li[5]/span[2]/a)))
+ ', ' + fetchText((x(//*[@id="body"]/div[1]/ul[1]/li[5]/div[2]/ul/li[1]/span[2])))
+ ', ' + fetchText((x(//*[@id="key"]))
+ ', ' + fetchText((x()))
+ ', ' + fetchText((x(//*[@id="body"]/div[1]/ul[1]/li[5]/div[2]/ul/li[2]/span[2])))
+ ', ' + fetchText((x(//*[@id="body"]/div[1]/ul[1]/li[5]/div[2]/ul/li[6]/span[2]/span[2]/a)))
+ ', ' + fetchText((x())));
return Array.prototype.map.call(info, function());
}
// This was changed.
casper.repeat(5, function() {
this.thenOpen(bURL + links[i], function() {
this.wait(3000);
info = info.concat(this.evaluate(getInfo));
});
i++;
}).run();
答案 0 :(得分:0)
您的代码存在多个问题。
您看到的解析错误是这一行:
return Array.prototype.map.call(info, function());
至少应该是
return Array.prototype.map.call(info, function(){});
对问题进行了编辑,以便此部分不再有意义。
这可能是一个错字,但这一行:
links = links.concat(this.evaluate(getLinks));
应该是
links = links.concat(this.evaluate(getInfo));
因为代码中没有getLinks
函数。
对问题进行了编辑,以便此部分不再有意义。
这样编写,你将以初始增量打开同一页5次,因为你增加了thenOpen
回调内部的增量。 CasperJS本质上是异步的,您只计划步骤(如thenOpen
调用)。
casper.repeat(5, function() {
this.thenOpen(googleSearch + '&start=' + increment, function() { ... });
increment += 10;
}).run();
您的wait(3000)
没有做任何事情,因为它是异步步骤函数,后跟同步evaluate
和concat
。步骤函数将在当前步骤结束时执行(此处为thenOpen
),但会立即执行同步函数。您可以使用then
的{{1}}回调来实现同步功能。所有wait
和所有then*
函数都是异步步骤函数。
wait*
XPath表达式不像正则表达式那样是javascript的原生表达式。没有XPath对象。 XPath是字符串,因此您需要引用它们。此
this.thenOpen(googleSearch + '&start=' + increment, function() {
this.wait(3000, function(){
// aggregate results for the 'BP' search
links = links.concat(this.evaluate(getLinks));
});
});
必须是
x(//*[@id="key"])
同样,x('//*[@id="key"]')
不是有效的XPath。
必须引用它,因为在字符串之外以x("")
开头的所有内容都是javascript中的注释。如果你做//
,你会得到很多未公开的括号。这就是XPath表示为字符串的原因。
现在你的脚本了。据我所知,你想从页面中获取一些文本并将它们作为数组发送到某个地方。
您在fetchText(x(//comment))
中使用document.querySelectorAll
表示getInfo
在页面上下文中执行(使用getInfo
),因为没有{{1}这样的内容在页面上下文之外。由于页面上下文执行是沙箱化的,因此您无法使用大多数CasperJS函数。只有__utils__
被注入页面上下文。 evaluate
不是其中之一,XPath实用程序document
也是如此,您必须将其添加到脚本的顶部:
fetchText
另一个奇怪的事情是你想要在x
中使用所选文本,这只是因为实际CSS选择器的文本可能没有,因为你正在刮取谷歌搜索。
接下来是
var x = require('casper').selectXPath;
将返回document.querySelectorAll
值的数组。
您不需要此页面上下文。你会在外面完成这个:
return Array.prototype.map.call(info, function(){});