使用Puppeteer访问Anthem登录页时HTTPS被转为HTTP致访问被拒
问题描述
使用Puppeteer v19.10.0访问https://www.anthem.com/login/时,原本合法的HTTPS URL被转为http://anthem.com/login/,截图显示**Access Denied You don't have permission to access "http://www.anthem.com/login/" on this server. Reference #18.9a....**错误。用wget测试同样失败,Firefox中观察到该页面由JS动态构建登录界面,怀疑是反爬机制识别出Puppeteer的自动化特征,需要将其模拟为真实Chrome浏览器。
相关代码及package.json配置如下:
const puppeteer = require('puppeteer'); function run() { return new Promise(async (resolve, reject) => { try { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://www.anthem.com/login/'); await page.screenshot({path: 'after-login.png'}); browser.close(); } catch (e) { return reject(e); } }); } run().then(console.log).catch(console.error);
{ "dependencies": { "puppeteer": "^19.10.0" } }
补充:该登录页包含49个网络请求,其中3个HTML请求、22个JS请求,反爬难度较高。
解决方案
以下是将Puppeteer模拟为真实Chrome的关键配置,直接修改代码即可:
- 启用新版无头模式:Puppeteer v19+支持
headless: "new",这个模式更接近真实有头Chrome的行为,避免旧无头模式的特征暴露 - 设置真实Chrome用户代理:复制当前Chrome浏览器的User-Agent字符串,替换默认的Puppeteer UA
- 禁用自动化检测特征:通过
page.evaluateOnNewDocument修改navigator.webdriver等属性,隐藏自动化标识 - 配置视口与浏览器尺寸:模拟真实用户的窗口大小
- 添加必要的HTTP请求头:比如
Accept-Language、Accept等,匹配真实浏览器的请求头 - 处理重定向与HTTPS:确保页面跳转时保持HTTPS协议,避免被强制降级
修改后的代码
const puppeteer = require('puppeteer'); async function run() { try { // 启动浏览器时配置真实Chrome特征 const browser = await puppeteer.launch({ headless: "new", // 新版无头模式,更接近真实Chrome args: [ '--no-sandbox', // 非必要,但部分环境需要 '--disable-setuid-sandbox', '--start-maximized', // 模拟窗口最大化 '--disable-blink-features=AutomationControlled' // 禁用自动化控制特征 ] }); const page = await browser.newPage(); // 设置真实Chrome的User-Agent(替换成你当前Chrome的UA) await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'); // 设置视口大小 await page.setViewport({ width: 1920, height: 1080 }); // 隐藏自动化标识 await page.evaluateOnNewDocument(() => { Object.defineProperty(navigator, 'webdriver', { get: () => undefined, }); // 额外隐藏其他可能的检测点 window.chrome = { runtime: {}, }; Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4], }); Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'], }); }); // 添加真实请求头 await page.setExtraHTTPHeaders({ 'Accept-Language': 'en-US,en;q=0.9', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' }); // 访问页面,等待JS加载完成 await page.goto('https://www.anthem.com/login/', { waitUntil: 'networkidle2', // 等待网络请求基本完成 timeout: 60000 // 延长超时时间,适配大量网络请求的页面 }); await page.screenshot({path: 'after-login.png'}); await browser.close(); console.log("操作完成"); } catch (e) { console.error("出错:", e); } } run();
额外注意事项
- User-Agent需要从你自己的Chrome浏览器中获取:打开Chrome开发者工具(F12),在Network标签下随便找一个请求,查看Request Headers里的
User-Agent字段 - 如果仍然被拦截,可以尝试添加页面交互,比如模拟鼠标移动、滚动,或者增加随机延迟,模拟真实用户行为
- 避免过快的请求频率,给页面足够的加载时间,可使用
page.waitForTimeout(1000)添加适当延迟
内容的提问来源于stack exchange,提问作者Woodsman
相关产品推荐
相关产品推荐

