Heroku环境下带请求头的Node.js HTTP请求失效如何解决?
解决Heroku环境下请求AccuWeather无响应的问题
我来帮你搞定这个Heroku上请求没反应的问题!从你的描述来看,核心原因应该是AccuWeather的反爬机制对请求的来源和请求头做了严格校验——Heroku的云环境本身带有一些特征,再加上你之前的请求头不够完整,才导致请求被拦截了。下面给你几个可行的解决方案:
1. 补全符合真实浏览器的完整请求头
很多反爬系统不会只检查User-Agent,还会验证Accept、Referer等多个字段,而且你之前用的User-Agent格式有多余空格和末尾的点,这也可能触发了校验。试试换成下面这个更完整的请求头配置:
var options = { url: 'https://www.accuweather.com/en/us/anchorage-ak/99501/daily-weather-forecast/346835?day=1', headers: { 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:117.0) Gecko/20100101 Firefox/117.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Referer': 'https://www.accuweather.com/', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1' } };
2. 添加超时和错误日志排查问题
有时候Heroku的网络延迟会导致请求超时,但默认不会抛出错误,让你误以为没响应。给请求加上超时配置,同时在回调里补充错误日志,能帮你快速定位问题:
var options = { // 保留上面的url和headers配置 timeout: 10000 // 设置10秒超时,避免无限等待 }; function callback(error, response, body) { if (error) { console.error('请求出错:', error); // 打印超时、连接失败等错误 return; } if (response.statusCode === 200) { var $ = cheerio.load(body); var title = $('div#header-logo > a:first-child > span').text(); console.log('title:', title); } else { console.log('响应状态码:', response.statusCode); // 比如403就是被反爬拦截了 } }
3. 检查Heroku的IP是否被拉黑
AccuWeather可能会拉黑云服务商的IP段(包括Heroku的),你可以在Heroku上执行这个命令测试:
heroku run curl -I https://www.accuweather.com
如果返回403 Forbidden,那就是IP被限制了,这时候可以考虑使用代理服务,给请求加上代理配置:
var options = { // 保留其他配置 proxy: 'http://your-proxy-address:port' // 替换为可用的代理地址 };
4. 优先考虑使用官方API
爬取网页很容易被反爬机制盯上,稳定性没保障。AccuWeather有官方的天气API,虽然需要申请密钥,但数据合法且稳定,长期来看比爬网页靠谱得多。
内容的提问来源于stack exchange,提问作者Mikhail
相关产品推荐
相关产品推荐

