Node.js使用request-promise无法请求OpenTable站点https链接问题求助
问题原因分析
你遇到的是典型的站点反爬虫拦截问题,OpenTable的安全防护策略比Instagram等站点更严格,会主动拦截特征明显的爬虫请求,具体可能的原因如下:
- 缺少合法请求头:request-promise默认发送的请求会携带
request-promise标识的User-Agent,这种特征明显的爬虫请求头会被OpenTable的Web应用防火墙直接拦截,同时请求缺少Accept、Accept-Language等浏览器默认头也会触发拦截规则。 - TLS指纹识别拦截:Node.js默认的TLS握手指纹和真实浏览器存在明显差异,OpenTable的反爬系统会校验JA3指纹,识别到是Node.js发起的请求就会直接拒绝访问。
- IP临时封禁:如果你短时间内向OpenTable发起了多次请求,你的IP地址可能会被临时封禁,导致无法正常获取响应。
- 代码缺失依赖引入:你当前的代码没有引入cheerio依赖,运行时会抛出引用错误,虽然这不是请求失败的直接原因,但会影响后续解析逻辑。
另外request库已经在2020年停止维护,本身存在很多已知问题,也建议你更换为axios、got等仍在活跃维护的请求库。
修复方案
方案1:补充合法请求头(最易实现,优先测试)
你可以在请求中添加模拟真实浏览器的请求头,绕过基础的反爬校验,修复后的代码如下:
// 提前安装依赖:npm install request-promise cheerio const request = require('request-promise'); const cheerio = require('cheerio'); (async () => { const BASE_URL = 'https://www.opentable.co.uk/s?dateTime=2021-05-30T19%3A00%3A00&covers=2&latitude=51.525225&longitude=-0.079615' // 模拟Chrome浏览器的标准请求头 const requestHeaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-GB,en;q=0.9', 'Cache-Control': 'max-age=0' } try { const response = await request({ uri: BASE_URL, headers: requestHeaders, followAllRedirects: true // 允许自动跟随301/302跳转 }) const $ = cheerio.load(response) console.log(response) } catch (error) { // 打印错误信息方便定位问题,比如返回的状态码、拦截页面内容 console.error('请求出错:', error.statusCode, error.response?.body) } })();
方案2:使用无头浏览器模拟真实访问
如果方案1仍然被拦截,说明站点触发了更严格的指纹校验,你可以使用puppeteer启动无头浏览器模拟真实用户访问,完全匹配浏览器的请求特征,代码示例如下:
// 提前安装依赖:npm install puppeteer cheerio const puppeteer = require('puppeteer'); const cheerio = require('cheerio'); (async () => { const BASE_URL = 'https://www.opentable.co.uk/s?dateTime=2021-05-30T19%3A00%3A00&covers=2&latitude=51.525225&longitude=-0.079615' // 启动浏览器 const browser = await puppeteer.launch({ headless: 'new' }) const page = await browser.newPage() // 跳转目标页面 await page.goto(BASE_URL, { waitUntil: 'networkidle2' }) // 获取页面HTML内容 const pageContent = await page.content() const $ = cheerio.load(pageContent) console.log(pageContent) // 关闭浏览器 await browser.close() })();
内容的提问来源于stack exchange,提问作者Christopher
相关产品推荐
相关产品推荐

