无GUI环境下Puppeteer/Headless Chromium报JSON解析错误求助
使用Puppeteer搭配Headless Chromium登录某网站时,页面加载JS文件出现以下错误:
[0726/133656.950429:INFO:CONSOLE(1)] "object err SyntaxError: Unexpected token < in JSON at position 0", source: https://***/_/horizon/p/_next/static/chunks/commons-e5cd62ffd659714024c3.js (1)
环境差异:
- 异常环境:无GUI环境(本地Docker Alpine Linux、VPS Debian),Chromium v102,Node.js v16.x
- 正常环境:本地Manjaro Linux(无Docker),Chromium v109,Node.js v16.x
当前Puppeteer配置:
{ headless: 'new', args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-accelerated-2d-canvas', '--disable-gpu', '--disable-features=DefaultPassthroughCommandDecoder', '--disable-web-security', '--disable-features=IsolateOrigins', '--disable-site-isolation-trials', ], dumpio: true, pipe: true, };
这个错误的核心原因是:本该返回合法JS/JSON的请求,实际返回了HTML内容(比如404页面、反爬拦截页面),HTML起始字符<导致JSON解析失败。无GUI环境的浏览器特征容易被网站反爬机制识别,以下是针对性解决步骤:
1. 对齐Chromium版本
本地正常环境用Chromium v109,异常环境是v102,版本差异会导致浏览器指纹不一致,触发反爬检测:
- 在无GUI环境安装v109版本的Chromium
- 或使用
puppeteer包而非puppeteer-core,让Puppeteer自动下载匹配版本的Chromium,避免依赖系统自带的旧版本
2. 优化浏览器指纹模拟,伪装真实浏览器
修改Puppeteer配置,添加模拟真实浏览器的参数,移除暴露异常的配置:
{ headless: 'new', args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-gpu', // 添加和本地Chrome版本一致的真实UA '--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', // 设置正常窗口大小 '--window-size=1920,1080', // 启用标准网络服务 '--enable-features=NetworkService,NetworkServiceInProcess', // 隐藏自动化控制标识 '--disable-blink-features=AutomationControlled', '--lang=en-US,en' ], dumpio: true, pipe: true, // 移除自动化提示标识 ignoreDefaultArgs: ['--enable-automation'], };
3. 捕获请求响应,排查实际返回内容
在脚本中添加response监听,查看出错的JS请求实际返回的内容,明确是404、反爬拦截还是其他问题:
page.on('response', async (response) => { const targetUrl = 'https://***/_/horizon/p/_next/static/chunks/commons-e5cd62ffd659714024c3.js'; if (response.url() === targetUrl) { console.log('请求状态码:', response.status()); const content = await response.text(); console.log('返回内容前500字符:', content.slice(0, 500)); } });
4. 处理资源加载问题
- 页面跳转或资源加载时,添加等待逻辑:
await page.goto('你的登录URL', { waitUntil: 'networkidle2', timeout: 60000 }); - 添加
--disable-cache到args中,禁用缓存避免旧资源干扰
5. Docker Alpine环境额外配置
Alpine Linux缺少部分依赖,可能导致浏览器特征异常,安装必要依赖包:
apk add --no-cache udev ttf-freefont chromium ca-certificates
或直接使用官方Puppeteer Docker镜像(puppeteer/puppeteer:19.8.0对应Chromium v109),避免手动处理依赖。
6. 进阶反爬绕过
如果以上方法无效,使用puppeteer-extra搭配stealth插件隐藏Headless特征:
- 安装依赖:
npm install puppeteer-extra puppeteer-extra-plugin-stealth - 修改脚本:
const puppeteer = require('puppeteer-extra'); const StealthPlugin = require('puppeteer-extra-plugin-stealth'); puppeteer.use(StealthPlugin()); // 后续正常初始化浏览器 const browser = await puppeteer.launch(/* 你的配置 */);
内容的提问来源于stack exchange,提问作者Alexander

