【发布时间】:2020-04-22 13:42:31
【问题描述】:
我正在构建一个网络爬虫来获取所有用户在 codeforces 上提交的内容。 我不太了解异步、等待、承诺。 我使用 axios(基于promise)请求codeforces 和cheerio 来解析HTML。
app.post("/", (req, res) => {
const usernameorhandle = req.body.userName;
getstatus(usernameorhandle).then ( ()=> {
var output = fs.createWriteStream(__dirname + '/Data/solutions.zip');
var archive = archiver('zip', {
zlib: { level: 9 } // Sets the compression level.
});
output.on('close', function() {
console.log(archive.pointer() + ' total bytes');
console.log('archiver has been finalized and the output file descriptor has closed.');
});
output.on('end', function() {
console.log('Data has been drained');
});
res.attachment(__dirname + "/Data/Problems", 'Codeforces-Solutions');
archive.pipe(res);
archive.directory(__dirname + "/Data/Problems", 'Codeforces-Solutions');
archive.finalize();
}) })
我用来接受发帖请求。 我将所有解决方案放入一个文件夹并创建 zip 文件夹,然后发送到 res。
下面是我的getstatus函数。
async function getstatus(handle){
return new Promise(async (resolve, reject)=> {
console.log("HELLLLLLLOOOOOOOO");
await axios.get("https://codeforces.com/api/user.status?handle=" + handle + "&from=1")
.then(response => {
if(response.data.status === 'OK'){
let results = response.data.result;
console.log("AAAAAAAAAAAAAAAAAAAAAAAa");
scrape(results).then( () =>{
console.log("DONE");
resolve();
})
.catch(err => console.log(err));
// resolve();
}
else console.log(submissions.comment);
})
})
}
我使用scrape函数来获取HTML数据并放到名为Problems的文件夹中。
async function scrape (results){
console.log("inside scrape");
// console.log("HELLO");
return new Promise( async (resolve, reject) => {
await results.forEach(async (result)=> {
if(result.verdict === 'OK'){
await axios.get("https://codeforces.com/contest/" + result.contestId + "/submission/" + result.id)
.then(solutionPage => {
const $ = cheerio.load(solutionPage.data);
const path = "/home/srujan/Desktop/crawlerapp/Data/Problems/" + result.problem.name + ".cpp";
fs.writeFile(path, $('#program-source-text').text(), function(err){
if(err){
console.log(err);
}
else{
console.log("Saved file");
}
})
})
.catch( error => {
console.log("HTML PARSE ERROR" + error);
})
}
})
console.log("hey");
resolve();
})
问题是我得到了
HELLLLLLLOOOOOOOO
AAAAAAAAAAAAAAAAAAAAAAAa
inside scrape
hey
DONE
saved file
saved file
...
DONE 后浏览器下载,然后保存文件。 我是 js 新手,不知道为什么会这样。
PS:我知道这是一个很长的问题。我尝试阅读很多关于此的内容。没有正确理解如何做到这一点。我复制粘贴了一些我不明白的代码,例如如何压缩文件夹。
【问题讨论】:
-
如果你想了解 async/await 和 promises,MDN docs 非常有用。
-
我读过,但我不知道我的代码有什么问题。
-
此外,res.attachment() 方法在您的响应中设置
Content-Disposition标头,这会使您的浏览器下载文件。所以这是预期的行为。这不是你想要达到的吗? -
是的,它会在完全收到响应后立即开始下载,因为响应具有
Content-Disposition标头。 -
await 关键字将为您提供已解决承诺的结果,一旦解决。它等待承诺解决,然后程序的其余部分才会继续。
标签: javascript node.js web-scraping promise async-await