从 CasperJS 中的无限滚动条中抓取动态呈现的链接
Scraping dynamically rendered links from an infinite scrollbar in CasperJS
我正在尝试使用 CasperJS 抓取 this page 左侧栏中的 link。
该页面的边栏中有数百个 link,但向下滚动时一次只加载 20 个。这段代码成功抓取前20个(需要全局安装casperjs和phantomjs到运行):
var casper = require('casper').create();
// helper function that gets all of the resume links on the page:
var getAllLinks = function() {
var linksOnThisPage = []
$("a[href^='/ResumeB']").each(function(index, linkDiv) {
$linkDiv = $(linkDiv)
linksOnThisPage.push('http://www.super-resume.com' + $linkDiv.attr('href'))
});
return linksOnThisPage
};
//start casper, go to page, run helper function:
casper.start('http://www.super-resume.com/ResumeBuilder.jtp?query=Database+Administrator', function() {
allLinks=casper.evaluate(getAllLinks)
console.log('number of links found:', allLinks.length);
});
casper.run();
我可以用这个在实际的浏览器中使页面向下滚动:
$('#search-left-inner').scrollTop(10000);
10000 是一个任意大的数字;每次您 运行 在浏览器中输入该代码时,它都会再加载 20 个 link。 (理想情况下,我希望能够一次抓取所有内容,而不必一次重新加载 20 个,但现在压力不大。)
如果我像这样将那行放在 getAllLinks
函数中:
var getAllLinks = function() {
$('#search-left-inner').scrollTop(10000);
var linksOnThisPage = []
//etc, etc,
它仍然只加载 20 link 秒。许多类似的帖子讨论了同步性问题,所以我试图让它等待侧边栏完成加载,包括以下几种方法:
var getAllLinks = function() {
casper.then(function () {
$('#search-left-inner').scrollTop(100000);
});
casper.then(function () {
var linksOnThisPage = []
//etc. etc.
}
但现在由于某种原因它只找到一个 link 而不是 20.
我假设如果您滚动,它不会立即加载下一个项目,因为加载需要时间。滚动后需要稍等片刻,然后才能尝试再次抓取所有元素。
casper.start(url)
.thenEvaluate(scroll)
.wait(5000, function(){
var links = this.evaluate(getAllLinks);
this.echo(links.length);
})
.run();
如果这会产生更多链接,那么您可以尝试下一步,即无限滚动,直到没有新元素加载为止。这可以通过 CasperJS 中的异步递归来完成:
var linkCount = -1;
function getAllLinks() {
var linksOnThisPage = []
$("a[href^='/ResumeB']").each(function(index, linkDiv) {
$linkDiv = $(linkDiv)
linksOnThisPage.push('http://www.super-resume.com' + $linkDiv.attr('href'))
});
return linksOnThisPage
}
function scroll() {
$('#search-left-inner').scrollTop(10000);
}
/**
* Returns true if more elements were loaded that were before
*/
function checkMore(){
var newLinks = this.evaluate(getAllLinks);
var newCount = newLinks.length;
if (linkCount === -1) {
linkCount = newCount;
}
return linkCount < newCount
}
/**
* Executes the a single iteration step and waits for a change in numbers.
* Terminates if there are no changes in 6 seconds.
*/
function step(){
this.thenEvaluate(scroll)
.waitFor(check, step, function _onTimeout(){
var links = this.evaluate(getAllLinks);
this.echo("finished with " + links.length + " links\n\n"+links.join("\n"));
}, 6000);
}
casper.start(url, step).run();
请记住,只有在该函数 casper.evaluate()
. I suggest that you also read the PhantomJS documentation 内部的 DOM 上下文(页面上下文)中使用 jQuery 才有意义。
我正在尝试使用 CasperJS 抓取 this page 左侧栏中的 link。
该页面的边栏中有数百个 link,但向下滚动时一次只加载 20 个。这段代码成功抓取前20个(需要全局安装casperjs和phantomjs到运行):
var casper = require('casper').create();
// helper function that gets all of the resume links on the page:
var getAllLinks = function() {
var linksOnThisPage = []
$("a[href^='/ResumeB']").each(function(index, linkDiv) {
$linkDiv = $(linkDiv)
linksOnThisPage.push('http://www.super-resume.com' + $linkDiv.attr('href'))
});
return linksOnThisPage
};
//start casper, go to page, run helper function:
casper.start('http://www.super-resume.com/ResumeBuilder.jtp?query=Database+Administrator', function() {
allLinks=casper.evaluate(getAllLinks)
console.log('number of links found:', allLinks.length);
});
casper.run();
我可以用这个在实际的浏览器中使页面向下滚动:
$('#search-left-inner').scrollTop(10000);
10000 是一个任意大的数字;每次您 运行 在浏览器中输入该代码时,它都会再加载 20 个 link。 (理想情况下,我希望能够一次抓取所有内容,而不必一次重新加载 20 个,但现在压力不大。)
如果我像这样将那行放在 getAllLinks
函数中:
var getAllLinks = function() {
$('#search-left-inner').scrollTop(10000);
var linksOnThisPage = []
//etc, etc,
它仍然只加载 20 link 秒。许多类似的帖子讨论了同步性问题,所以我试图让它等待侧边栏完成加载,包括以下几种方法:
var getAllLinks = function() {
casper.then(function () {
$('#search-left-inner').scrollTop(100000);
});
casper.then(function () {
var linksOnThisPage = []
//etc. etc.
}
但现在由于某种原因它只找到一个 link 而不是 20.
我假设如果您滚动,它不会立即加载下一个项目,因为加载需要时间。滚动后需要稍等片刻,然后才能尝试再次抓取所有元素。
casper.start(url)
.thenEvaluate(scroll)
.wait(5000, function(){
var links = this.evaluate(getAllLinks);
this.echo(links.length);
})
.run();
如果这会产生更多链接,那么您可以尝试下一步,即无限滚动,直到没有新元素加载为止。这可以通过 CasperJS 中的异步递归来完成:
var linkCount = -1;
function getAllLinks() {
var linksOnThisPage = []
$("a[href^='/ResumeB']").each(function(index, linkDiv) {
$linkDiv = $(linkDiv)
linksOnThisPage.push('http://www.super-resume.com' + $linkDiv.attr('href'))
});
return linksOnThisPage
}
function scroll() {
$('#search-left-inner').scrollTop(10000);
}
/**
* Returns true if more elements were loaded that were before
*/
function checkMore(){
var newLinks = this.evaluate(getAllLinks);
var newCount = newLinks.length;
if (linkCount === -1) {
linkCount = newCount;
}
return linkCount < newCount
}
/**
* Executes the a single iteration step and waits for a change in numbers.
* Terminates if there are no changes in 6 seconds.
*/
function step(){
this.thenEvaluate(scroll)
.waitFor(check, step, function _onTimeout(){
var links = this.evaluate(getAllLinks);
this.echo("finished with " + links.length + " links\n\n"+links.join("\n"));
}, 6000);
}
casper.start(url, step).run();
请记住,只有在该函数 casper.evaluate()
. I suggest that you also read the PhantomJS documentation 内部的 DOM 上下文(页面上下文)中使用 jQuery 才有意义。