CasperJS - 如何从数组中为每个页面保存一些数据?
CasperJS - How to save some data for each page from an array?
我正在尝试使用 CasperJS 抓取网站,但我 运行 遇到了问题。
在第一页中,我收集了我想要抓取的链接,并使用 getLinks()
函数将它们保存到一个数组中 - 这很有效。
然后我想从这个数组中抓取每个页面(我让这部分工作)并且我想从每个页面中获取一些细节。
我的代码如下(修剪了 casper 启动和登录等工作内容):
// Casper start here, and some login stuff, all these are working fine so I removed them to have a light example
// ....
// ....
// ....
// Function for saving members to an array
function getLinks() {
var links = document.querySelectorAll(".member_name_and_title");
return Array.prototype.map.call(links, function(link) {
return link.childNodes[1].childNodes[1].href
});
}
casper.then(function() {
// Aggregate results
links = this.evaluate(getLinks);
casper.each(links, function (self, link) {
self.thenOpen(link, function () {
var details = this.evaluate(function(){
document.getElementsByClassName('member_name')[0].textContent;
});
// Grab details for each member
var data = details + " - " + link;
// Save data
var fs = require('fs');
fs.write('results/output.txt', JSON.stringify(data, null, ' '), 'aw');
});
});
});
// Casper run
casper.run(function() {
this.exit();
});
问题是 details
var 将 return 为 null,所以最终的 output.txt
将类似于:
"null - domain.com/link1"
"null - domain.com/link2"
"null - domain.com/link3"
"null - domain.com/link4"
"null - domain.com/link5"
link
var 工作正常但 details
var 为 returning null。
当我在浏览器控制台中访问数组中的任何 url(例如:domain.com/link1)和 运行 document.getElementsByClassName('member_name')[0].textContent
时,它 return 是值正确,所以我确定定位没问题。
我不确定自己遗漏了什么或做错了什么。任何帮助将非常感激。谢谢!
尝试添加一个 return,如下所述:
var details = this.evaluate(function(){
return document.getElementsByClassName('member_name')[0].textContent;
});
编辑:
这对我有用。我的代码设置如下:
var casper = require('casper').create();
function getLinks() {
var matchedLinks = document.querySelectorAll(".member_name_and_title");
return Array.prototype.map.call(matchedLinks, function(link) {
return link.href;
});
}
casper.start('http://localhost:8080');
casper.then(function() {
// Aggregate results
links = this.evaluate(getLinks);
casper.each(links, function (self, link) {
// INSPECT: Check if it shows the correct link here.
self.echo('Opening link:' + link);
self.thenOpen(link, function () {
var details = this.evaluate(function(){
// INSPECT: Make sure to 'return' the text content.
return document.getElementsByClassName('member_name')[0].textContent;
});
// Grab details for each member
var data = details + " - " + link;
// INSPECT: Check if the data is correct.
self.echo(data);
// Save data
var fs = require('fs');
fs.write('results/output.txt', JSON.stringify(data, null, ' '), 'aw');
});
});
});
casper.run(function(){
this.exit();
});
我的html个文件如下:
index.html
<!DOCTYPE html>
<html>
<head>
<title>Hello CasperJs</title>
</head>
<body>
<a href="page1.html" class="member_name_and_title">Page 1</a>
<a href="page2.html" class="member_name_and_title">Page 2</a>
<a href="page3.html" class="member_name_and_title">Page 3</a>
<a href="page4.html" class="member_name_and_title">Page 4</a>
</body>
</html>
page1.html
<!DOCTYPE html>
<html>
<head>
<title>Page 1 Title</title>
</head>
<body>
<p class="member_name">Page 1 Text</p>
</body>
</html>
page2.html、page3.html 和 page4.html 的类似 HTML 标记。我的 http 服务器 运行 在 8080 端口。
我的控制台输出如下:
Opening link:http://localhost:8080/page1.html
Opening link:http://localhost:8080/page2.html
Opening link:http://localhost:8080/page3.html
Opening link:http://localhost:8080/page4.html
Page 1 Text - http://localhost:8080/page1.html
Page 2 Text - http://localhost:8080/page2.html
Page 3 Text - http://localhost:8080/page3.html
Page 4 Text - http://localhost:8080/page4.html
我正在使用 casperjs 1.1.3 和 phantomjs 2.1.1。
你能更新你的代码并分享你的控制台输出和包版本吗?
好吧,我最终弄明白了,完全是菜鸟错误...查询是正确的问题是由页面加载引起的,或者更好的说法是在实际查询之前未加载数组中的链接运行。
为了测试这一点,我在 self.thenOpen
函数中使用了 captureSelection() 来捕获页面打开时的状态,但就在收集数据之前。
this.captureSelector('1.jpg', '#page');
我立即注意到页面未完全加载,因此 return document.querySelector('.member_name.').textContent;
返回 null
。
为了解决这个问题,我添加了 1.5 秒的等待时间,如下所示:
casper.wait(1500, function() {
var details = this.evaluate(function(){
return document.querySelector('.member_name').textContent;
});
});
新手错误,但将来可能会帮助其他人。
我正在尝试使用 CasperJS 抓取网站,但我 运行 遇到了问题。
在第一页中,我收集了我想要抓取的链接,并使用 getLinks()
函数将它们保存到一个数组中 - 这很有效。
然后我想从这个数组中抓取每个页面(我让这部分工作)并且我想从每个页面中获取一些细节。
我的代码如下(修剪了 casper 启动和登录等工作内容):
// Casper start here, and some login stuff, all these are working fine so I removed them to have a light example
// ....
// ....
// ....
// Function for saving members to an array
function getLinks() {
var links = document.querySelectorAll(".member_name_and_title");
return Array.prototype.map.call(links, function(link) {
return link.childNodes[1].childNodes[1].href
});
}
casper.then(function() {
// Aggregate results
links = this.evaluate(getLinks);
casper.each(links, function (self, link) {
self.thenOpen(link, function () {
var details = this.evaluate(function(){
document.getElementsByClassName('member_name')[0].textContent;
});
// Grab details for each member
var data = details + " - " + link;
// Save data
var fs = require('fs');
fs.write('results/output.txt', JSON.stringify(data, null, ' '), 'aw');
});
});
});
// Casper run
casper.run(function() {
this.exit();
});
问题是 details
var 将 return 为 null,所以最终的 output.txt
将类似于:
"null - domain.com/link1"
"null - domain.com/link2"
"null - domain.com/link3"
"null - domain.com/link4"
"null - domain.com/link5"
link
var 工作正常但 details
var 为 returning null。
当我在浏览器控制台中访问数组中的任何 url(例如:domain.com/link1)和 运行 document.getElementsByClassName('member_name')[0].textContent
时,它 return 是值正确,所以我确定定位没问题。
我不确定自己遗漏了什么或做错了什么。任何帮助将非常感激。谢谢!
尝试添加一个 return,如下所述:
var details = this.evaluate(function(){
return document.getElementsByClassName('member_name')[0].textContent;
});
编辑:
这对我有用。我的代码设置如下:
var casper = require('casper').create();
function getLinks() {
var matchedLinks = document.querySelectorAll(".member_name_and_title");
return Array.prototype.map.call(matchedLinks, function(link) {
return link.href;
});
}
casper.start('http://localhost:8080');
casper.then(function() {
// Aggregate results
links = this.evaluate(getLinks);
casper.each(links, function (self, link) {
// INSPECT: Check if it shows the correct link here.
self.echo('Opening link:' + link);
self.thenOpen(link, function () {
var details = this.evaluate(function(){
// INSPECT: Make sure to 'return' the text content.
return document.getElementsByClassName('member_name')[0].textContent;
});
// Grab details for each member
var data = details + " - " + link;
// INSPECT: Check if the data is correct.
self.echo(data);
// Save data
var fs = require('fs');
fs.write('results/output.txt', JSON.stringify(data, null, ' '), 'aw');
});
});
});
casper.run(function(){
this.exit();
});
我的html个文件如下:
index.html
<!DOCTYPE html>
<html>
<head>
<title>Hello CasperJs</title>
</head>
<body>
<a href="page1.html" class="member_name_and_title">Page 1</a>
<a href="page2.html" class="member_name_and_title">Page 2</a>
<a href="page3.html" class="member_name_and_title">Page 3</a>
<a href="page4.html" class="member_name_and_title">Page 4</a>
</body>
</html>
page1.html
<!DOCTYPE html>
<html>
<head>
<title>Page 1 Title</title>
</head>
<body>
<p class="member_name">Page 1 Text</p>
</body>
</html>
page2.html、page3.html 和 page4.html 的类似 HTML 标记。我的 http 服务器 运行 在 8080 端口。
我的控制台输出如下:
Opening link:http://localhost:8080/page1.html
Opening link:http://localhost:8080/page2.html
Opening link:http://localhost:8080/page3.html
Opening link:http://localhost:8080/page4.html
Page 1 Text - http://localhost:8080/page1.html
Page 2 Text - http://localhost:8080/page2.html
Page 3 Text - http://localhost:8080/page3.html
Page 4 Text - http://localhost:8080/page4.html
我正在使用 casperjs 1.1.3 和 phantomjs 2.1.1。
你能更新你的代码并分享你的控制台输出和包版本吗?
好吧,我最终弄明白了,完全是菜鸟错误...查询是正确的问题是由页面加载引起的,或者更好的说法是在实际查询之前未加载数组中的链接运行。
为了测试这一点,我在 self.thenOpen
函数中使用了 captureSelection() 来捕获页面打开时的状态,但就在收集数据之前。
this.captureSelector('1.jpg', '#page');
我立即注意到页面未完全加载,因此 return document.querySelector('.member_name.').textContent;
返回 null
。
为了解决这个问题,我添加了 1.5 秒的等待时间,如下所示:
casper.wait(1500, function() {
var details = this.evaluate(function(){
return document.querySelector('.member_name').textContent;
});
});
新手错误,但将来可能会帮助其他人。