Scrapy爬取非标准JSON触发JSONDecodeError,寻求解决办法
解决Scrapy爬取非标准JSON时的JSONDecodeError问题
你遇到的问题很常见:目标返回的内容不是标准JSON格式,而是被data()函数调用包裹的JSONP结构,直接用json.loads(response.body_as_unicode())自然会触发JSONDecodeError——因为标准JSON的根节点只能是对象或数组,而你的内容外层多了函数包装。下面是几个实用的解决办法:
方法1:字符串切片提取核心JSON内容
最直接的方式就是手动剥离外层的data()包裹,提取括号里的JSON数组:
import json def parse(self, response): raw_content = response.body_as_unicode() # 定位括号位置,提取中间的JSON字符串 start_pos = raw_content.find('(') + 1 end_pos = raw_content.rfind(')') clean_json = raw_content[start_pos:end_pos].strip() # 现在可以正常解析了 data_list = json.loads(clean_json) # 后续处理逻辑...
这个方法简单高效,适合你这种结构固定的情况——只要外层始终是data(...)的格式就没问题。
方法2:正则表达式匹配提取
如果担心内容里有额外的空格、换行或者格式小变动,用正则表达式会更灵活:
import re import json def parse(self, response): raw_content = response.body_as_unicode() # 匹配data(...)里的所有内容,支持换行 pattern = re.compile(r'data\(\s*(.*?)\s*\)', re.DOTALL) match_result = pattern.search(raw_content) if match_result: clean_json = match_result.group(1) data_list = json.loads(clean_json) # 后续处理逻辑...
re.DOTALL参数能让正则里的.匹配换行符,就算JSON内容跨多行也能正确提取。
方法3:用第三方库处理JSONP格式
如果你的场景经常遇到JSONP格式,可以用专门的库来简化处理,比如demjson:
首先安装库:
pip install demjson
然后在Scrapy的解析函数里使用:
import demjson def parse(self, response): raw_content = response.body_as_unicode() # 去掉外层的data(和末尾的) cleaned_content = raw_content.replace('data(', '').rstrip(')') data_list = demjson.decode(cleaned_content) # 后续处理逻辑...
不过这个方法依赖第三方库,如果你只是偶尔遇到这种情况,前两种原生方法足够满足需求。
内容的提问来源于stack exchange,提问作者Anoop D
相关产品推荐
相关产品推荐

