为何while循环内的Axios GET请求未被执行?(网页爬取场景)
Axios请求被忽略的核心原因
同步循环与异步请求的逻辑冲突
你的while循环是同步阻塞的,但Axios发起的HTTP请求是异步非阻塞的。当代码执行到Axios请求时,不会等待请求响应返回,直接回到while的条件判断(此时fighterFound还是false,next已被重置为0),循环会立刻开始重复遍历当前页的旧数据,完全不会等待新页面的请求结果,导致新请求的响应还没处理,循环已经进入下一轮,看起来就像请求被忽略了。未在异步回调中更新循环依赖的核心变量
即使Axios请求成功拿到了下一页数据,你也只是把响应存成了图片(response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))),没有在.then()回调里更新fighterNameFound和fighterNameIndex这两个循环依赖的变量,更没有把新页面的内容纳入查找流程。相当于请求发起后,结果完全没参与到后续的拳手查找逻辑中,等于白发起了请求。循环逻辑陷入无意义的死循环
因为异步请求的结果无法影响同步的while循环,循环会一直重复遍历当前页的旧数据,永远无法推进到新页面的内容,同时会不断发起新的Axios请求,但这些请求的结果都无法被处理,最终表现为请求被“忽略”。
简单修复思路
把同步的while循环改成异步循环,使用async/await来等待Axios请求完成,再更新变量并继续查找:
// 把外层函数改成async app.get('/api/fighter', async (req,res) => { let userAgent = randomUseragent.getRandom(); req.headers['user-agent'] = userAgent; let firstName = "jon" let lastName = "jones" let initialUrlToScrape = `https://www.sherdog.com/stats/fightfinder?SearchTxt=${firstName}+${lastName}&weight=&association=`; // 用await替代回调式的request const initialResponse = await axios({ url: initialUrlToScrape, headers: { 'User-Agent': req.headers['user-agent'] } }); const $ = cheerio.load(initialResponse.data); let fighterNameIndex = $('.new_table td a'); let nameToCompare = `${firstName} ${lastName}`; let fighterFound = false; let next=0; let page = 1; while (!fighterFound) { if(next >= fighterNameIndex.length){ // 发起下一页请求并等待结果 page++; const nextPageResponse = await axios({ url: `https://www.sherdog.com/stats/fightfinder?association=&weightclass=&SearchTxt=jon+jones&page=${page}`, headers: { 'User-Agent': req.headers['user-agent'] } }); // 解析新页面的HTML,更新变量 const $next = cheerio.load(nextPageResponse.data); fighterNameIndex = $next('.new_table td a'); next = 0; continue; } const currentName = fighterNameIndex[next].children[0].data.toLowerCase(); if(currentName === nameToCompare.toLowerCase()){ // 找到目标拳手,获取个人页面URL const profileUrl = `https://www.sherdog.com${fighterNameIndex[next].attribs.href}`; // 爬取个人页面逻辑 const profileResponse = await axios({ url: profileUrl, headers: { 'User-Agent': req.headers['user-agent'] } }); const $profile = cheerio.load(profileResponse.data); // 解析个人页面数据 const fullnameValue = $profile('.fighter-title h1 .fn').text(); const nickNameValue = $profile('.fighter-title h1 .nickname, .fighter-title h1 .nickname_empty').text(); const birthCountryValue = $profile('.fighter-title .birthplace strong').text(); const fightingOutOfValue = $profile('span.locality').text(); const flagValue = $profile('.fighter-title .big_flag').attr('src'); const winsValue = $profile('div.winloses.win span').text().replace("Wins",""); const lossesValue = $profile('div.winloses.lose span').text().replace("Losses",""); const weightClassValue = $profile('body > div.wrapper > div.inner-wrapper > div.col-left > div > section:nth-child(3) > div > div.fighter-info > div.fighter-right > div.fighter-data > div.bio-holder > div > a').text(); data.push({ name: fullnameValue, nickname: nickNameValue, country: birthCountryValue, fightingOutOf: fightingOutOfValue, flag: `https://www.sherdog.com${flagValue}`, wins: winsValue, losses: lossesValue, weightClass: weightClassValue }) res.send(data); fighterFound = true; } else { next++; } } })
内容的提问来源于stack exchange,提问作者Suraj
相关产品推荐
相关产品推荐

