使用 Cheerio 抓取许多网站
Using Cheerio for scraping many sites
我正在使用 cheerio
抓取大约 800 个网站,以获取网站标题。我遇到的第一个问题是有时我会收到一条错误消息 "We’ve encountered an error: Error: socket hang up"。其次,可能是因为 cheerio
的异步性质,当我记录创建的 objects 时,它们都具有数组中最后一个网址的地址。最后,我记录了我一直将 objects 推入的数组,但它实际上是立即将其记录为 []
,因为它在执行任何其他操作之前完成了此操作。我该如何解决这三个问题?我去过
var tempArr = [];
var completedLinks = ["http://www.example.com/page1", "http://www.example.com/page2", "http://www.example.com/page3"...];
for (var foundLink in completedLinks){
if(ValidURL(completedLinks[foundLink])){
request(completedLinks[foundLink], function (error, response, body) {
if (!error) {
var $ = cheerio.load(body);
var titles = $("title").text();
var tempObj = {};
tempObj.title = titles;
tempObj.address = completedLinks[foundLink]
tempArr.push(tempObj);
console.log(tempObj)
}else{
console.log("We’ve encountered an error: " + error);
}
});
}
}
console.log(tempArr);
您的挂断可能是因为许多网站实施了速率限制。我猜想这些错误往往发生在网站的第 2 页上。您可能想要做的一件事是按主机将您的链接组织到列表中,并使用 setTimeout 在第一次调用该主机后限制每个调用。
您的 "last web address" 问题是关于范围的经典 JavaScript 问题。至少你应该在一个函数中处理每个请求:
function processLink(link){
if(ValidURL(link)...
}
然后
for (var foundLink in completedLinks){
processLink(completedLinks[foundLink]);
}
终于等到所有都完成后再退出你应该考虑Promises
忽略节流问题:
function processLink(link){
return new Promise(function(resolve, reject) {
request(link, function (error, response, body) {
if (!error) {
resolve(tempObj);
}
});
});
};
var promises = [];
for (var foundLink in completedLinks){
promises.push(processLink(completedLinks[foundLink]));
}
Promise.all(promises).then(function(tempObjArr){...});
我正在使用 cheerio
抓取大约 800 个网站,以获取网站标题。我遇到的第一个问题是有时我会收到一条错误消息 "We’ve encountered an error: Error: socket hang up"。其次,可能是因为 cheerio
的异步性质,当我记录创建的 objects 时,它们都具有数组中最后一个网址的地址。最后,我记录了我一直将 objects 推入的数组,但它实际上是立即将其记录为 []
,因为它在执行任何其他操作之前完成了此操作。我该如何解决这三个问题?我去过
var tempArr = [];
var completedLinks = ["http://www.example.com/page1", "http://www.example.com/page2", "http://www.example.com/page3"...];
for (var foundLink in completedLinks){
if(ValidURL(completedLinks[foundLink])){
request(completedLinks[foundLink], function (error, response, body) {
if (!error) {
var $ = cheerio.load(body);
var titles = $("title").text();
var tempObj = {};
tempObj.title = titles;
tempObj.address = completedLinks[foundLink]
tempArr.push(tempObj);
console.log(tempObj)
}else{
console.log("We’ve encountered an error: " + error);
}
});
}
}
console.log(tempArr);
您的挂断可能是因为许多网站实施了速率限制。我猜想这些错误往往发生在网站的第 2 页上。您可能想要做的一件事是按主机将您的链接组织到列表中,并使用 setTimeout 在第一次调用该主机后限制每个调用。
您的 "last web address" 问题是关于范围的经典 JavaScript 问题。至少你应该在一个函数中处理每个请求:
function processLink(link){
if(ValidURL(link)...
}
然后
for (var foundLink in completedLinks){
processLink(completedLinks[foundLink]);
}
终于等到所有都完成后再退出你应该考虑Promises
忽略节流问题:
function processLink(link){
return new Promise(function(resolve, reject) {
request(link, function (error, response, body) {
if (!error) {
resolve(tempObj);
}
});
});
};
var promises = [];
for (var foundLink in completedLinks){
promises.push(processLink(completedLinks[foundLink]));
}
Promise.all(promises).then(function(tempObjArr){...});