我在下面创建了一个脚本,从这个website中收集省下的所有链接,然后访问单个链接来收集office下的所有链接,最后从目标页面中刮取标题。
脚本在从第一个链接刮取标题后卡住了。我对Promise很陌生,所以我不知道这个问题。
这是我得出的结论:
const request = require('request');
const cheerio = require('cheerio');
const link = 'https://egpostal.com/en/p/all';
const base_link = 'https://egpostal.com/en/';
const landing_page_links = [];
const inner_page_links = [];
let getLinks = () => {
return new Promise((resolve, reject) => {
request(link, function(error, response, html) {
let $ = cheerio.load(html);
if (error) return reject(error);
try {
$('.table tbody tr').each(function() {
landing_page_links.push(base_link + $(this).find("a").attr("href"));
});
resolve(landing_page_links);
} catch (e) {
reject(e);
}
});
});
};
let getInnerLinks = (links) => {
return new Promise((resolve, reject) => {
for (let url of links) {
request(url, function(error, response, html) {
let $ = cheerio.load(html);
if (error) return reject(error);
try {
$('.table tbody tr').each(function() {
inner_page_links.push(base_link + $(this).find("a").attr("href"));
});
resolve(inner_page_links);
} catch (e) {
reject(e);
}
});
}
});
};
let FetchTitle = (links) => {
return new Promise((resolve, reject) => {
for (let url of links) {
request(url, function(error, response, html) {
let $ = cheerio.load(html);
if (error) return reject(error);
try {
resolve($(".home-title > h2").eq(0).text());
} catch (e) {
reject(e);
}
})
}
})
}
getLinks().then(resultList => {
getInnerLinks(resultList).then(resultSet => {
FetchTitle(resultSet).then(title =>{
console.log(title);
})
})
})
2条答案
按热度按时间j9per5c41#
首先是request is deprecated,所以你应该避开这个包,既然你想和 promises 一起工作,我建议你改用axios。
老实说,如果我是你,我会使用一个爬行库来使事情变得更容易和更健壮。但我想这或多或少是一个编码挑战,所以我将把你的代码“原样”,并调整它,使它工作。
这里的主要问题是
getInnerLinks
,您在一个request回调中解决您的承诺,回调本身在一个循环中。如果第一次迭代是OK的,您的脚本将通过主承诺链中的.then()
跳到下一步。因此,实际上,在循环之后解决您的承诺更合乎逻辑。但是考虑到所有请求都是异步的,您需要等待。setTimeout()
在这种情况下对运行一些测试很有用。现在的问题是:你要等多久?嗯...当你玩弄许多承诺时,一个可靠而安全的解决方案是使用Promise.all()
。而且,一个对
FetchTitle
的承诺是大材小用,你可以直接把一个console.log()
放进去打印标题。下面是代码:
mo49yndu2#
这种网页抓取非常适合Python上的
scrapy
。步骤
它将创建文件
在这些文件中,我们只会接触到两个文件(items.py和post_office. py)
使用此代码覆盖两个文件
邮局. py
网站items.py
运行并保存到result.json中
如果您成功完成了这些步骤,您可以在终端中看到一些登录信息。(* 注意-O是大写字母)