爬取分页网站帖子时,如何在Axios捕获404时终止for循环?
解决Axios爬取分页时遇404无法终止循环的问题
你的问题出在同步循环+异步请求的矛盾上:原来的for循环是同步执行的,会一次性把所有600页的请求都塞进allLinks数组里,不管请求有没有返回,循环已经跑完了,所以catch里的break根本触不到循环逻辑。
正确的做法是改成异步逐个请求,用async/await让循环等当前请求完成后,再决定是否继续下一页。修改后的代码如下:
async getMaxPageAmount(url: any) { let maxPage = 600; let collection: string[][] = []; for (let i = 1; i < maxPage; i++) { try { const urlResponse = await axios.get(url + i + "/"); let $ = cheerio.load(urlResponse.data); $("div.main-posts").each((_, element) => { let links = $(element) .find("div#entry-pic a") .get() .map(x => $(x).attr('href') || ''); collection.push(links); console.log(collection); }); } catch (reason: any) { if (reason.response?.status === 404) { console.log(`第${i}页不存在,终止爬取`); break; // 这里的break能直接终止for循环 } // 处理其他错误,比如网络超时等 console.error(`爬取第${i}页出错:`, reason.message); } } console.log("所有爬取的链接:", collection); return collection; }
关键改动说明:
- 把函数声明为
async,这样可以在内部使用await等待每个请求完成 - 去掉了
allLinks数组和Promise.all,改成逐个请求、逐个处理 - 用
try/catch包裹单个请求,捕获到404时直接break终止循环 - 调整了类型声明(比如
collection: string[][]),让代码更规范 - 处理了
attr('href')可能返回undefined的情况,默认空字符串
这样修改后,爬取会从第1页开始,每爬完一页再请求下一页,一旦遇到404就立刻停止循环,不会再发送后续请求。
内容的提问来源于stack exchange,提问作者ChopperChupss
相关产品推荐
相关产品推荐

