Node.js使用Nightmare获取JSON解析遇Promise拒绝及语法错误求助
解决Nightmare获取JSON后JSON.parse出现特殊字符的错误
Hey there, let's break down why you're seeing that weird Unexpected token ☻ error and fix it!
问题根源
那个☻是不可打印的控制字符,说明你通过document.body.innerText拿到的内容不是纯净的JSON——它大概率混杂了页面里的其他文本、空格、隐藏的特殊字符,甚至是页面加载过程中残留的非JSON内容。直接对整个body的文本做JSON.parse肯定会出错。
具体解决方案
1. 定位正确的JSON数据源(最推荐)
绝大多数网站不会把纯JSON直接放在body的innerText里,常见的做法是:
- 把JSON放在
<script type="application/json">标签中 - 或者存在某个全局变量里(比如
window.__INITIAL_DATA__ = {...})
你需要先在目标页面的开发者工具里找到JSON的具体位置,然后针对性提取:
var nightmare = Nightmare() .goto('URL') // 换成等待目标元素出现,比固定等待时间更可靠 .wait('script[type="application/json"]') .evaluate(() => { // 假设JSON在type为application/json的script标签里 const jsonScript = document.querySelector('script[type="application/json"]'); return jsonScript ? jsonScript.textContent : ''; }) .end() .then((jsonText) => { var data; try { data = JSON.parse(jsonText); } catch(e) { console.log('解析错误:', e); } callback(null, data); });
2. 清理文本中的特殊字符(应急方案)
如果确实只能从body.innerText里提取,先清除所有不可打印的控制字符再解析:
var nightmare = Nightmare() .goto('URL') .wait(10000) .evaluate(() => { return document.body.innerText; }) .end() .then((body) => { var data; try { // 清除所有ASCII控制字符(包括那个☻) const cleanedBody = body.replace(/[\x00-\x1F\x7F-\x9F]/g, ''); // 还可以进一步过滤,只保留JSON结构部分(比如匹配{}或[]包裹的内容) const jsonMatch = cleanedBody.match(/\{.*\}/s) || cleanedBody.match(/\[.*\]/s); if (jsonMatch) { data = JSON.parse(jsonMatch[0]); } } catch(e) { console.log('解析错误:', e); // 打印部分文本看看里面混了什么 console.log('文本片段:', body.slice(0, 2000)); } callback(null, data); });
3. 优化等待逻辑
固定wait(10000)很不可靠——如果页面加载慢,JSON还没出现;如果加载快,又浪费时间。换成等待JSON内容出现的条件:
.wait(() => { // 假设JSON里有某个特定的key,比如"userId" return document.body.innerText.includes('"userId":'); })
调试小技巧
在catch块里打印获取到的文本片段(比如前2000个字符),能快速看到里面到底混了什么内容(比如HTML注释、广告文本、加载动画的文字等),帮你更快定位问题。
内容的提问来源于stack exchange,提问作者Lixx Sed
相关产品推荐
相关产品推荐

