我在Apify (jQuery) 中编写了以下网络爬虫,但我正在努力将其限制为仅查看某些列表页面。
爬虫会抓取我在https://www.beet.tv/author/randrews上发表的文章,该页面包含 102 个分页索引页面,每个页面包含 20 个文章链接。爬虫在手动和完全执行时工作正常;它得到了一切,2,000 多篇文章。
但是,我希望使用Apify 的调度程序来触发偶尔的抓取,该抓取仅从这些索引 (LIST) 页面的前三个(即 60 篇文章)中抓取文章。
调度程序使用 cron 并允许通过输入 Json 传递设置。按照建议,我正在使用“customData”...
{
"customData": 3
}
...然后下面取该值并用它来限制...
var maxListDepth = parseInt(context.customData); // Jakub's suggestion, Nov 20 2018
if(!maxListDepth || (maxListDepth && pageNumber <= maxListDepth)) {
context.enqueuePage({
这应该允许脚本在通过调度程序执行时限制范围,但在手动执行时正常进行并完整获取所有内容。
然而,虽然调度器成功地触发了爬虫——爬虫仍然会再次运行整个集合;它不会在 /page/3 处结束。
如何确保我只获得前三页到 /page/3?
我有什么畸形吗?
在代码中,您可以看到我之前添加的上述版本,现在已被注释掉。
那些 LIST 页面应该只是......
- STARTing 一个,带有隐含的“/page/1” URL ( https://www.beet.tv/author/randrews )
- https://www.beet.tv/author/randrews/page/2
- https://www.beet.tv/author/randrews/page/3
... 而不是 /page/101 或 /page/102 之类的,它们可能会浮出水面。
以下是关键术语...
START https://www.beet.tv/author/randrews
LIST https://www.beet.tv/author/randrews/page/[\d+]
DETAIL https://www.beet.tv/*
Clickable elements a.page-numbers
这是爬虫脚本...
function pageFunction(context) {
// Called on every page the crawler visits, use it to extract data from it
var $ = context.jQuery;
// If page is START or a LIST,
if (context.request.label === 'START' || context.request.label === 'LIST') {
context.skipOutput();
// First, gather LIST page
$('a.page-numbers').each(function() {
// lines added to accept number of pages via customData in Scheduler...
var pageNumber = parseInt($(this).text());
// var maxListDepth = context.customData;
var maxListDepth = parseInt(context.customData); // Jakub's suggestion, Nov 20 2018
if(!maxListDepth || (maxListDepth && pageNumber <= maxListDepth)) {
context.enqueuePage({
url: /*window.location.origin +*/ $(this).attr('href'),
label: 'LIST'
});
}
});
// Then, gather every DETAIL page
$('h3>a').each(function(){
context.enqueuePage({
url: /*window.location.origin +*/ $(this).attr('href'),
label: 'DETAIL'
});
});
// If page is actually a DETAIL target page
} else if (context.request.label === 'DETAIL') {
/* context.skipLinks(); */
var categories = [];
$('span.cat-links a').each( function() {
categories.push($(this).text());
});
var tags = [];
$('span.tags-links a').each( function() {
tags.push($(this).text());
});
result = {
"title": $('h1').text(),
"entry": $('div.entry-content').html().trim(),
"datestamp": $('time').attr('datetime'),
"photo": $('meta[name="twitter:image"]').attr("content"),
categories: categories,
tags: tags
};
}
return result;
}