Scrapy爬取snl24新闻遇两大问题:内容不符+无数据爬取
解决Scrapy爬取snl24无限滚动新闻的问题
问题1:分页URL爬取的HTML与开发者工具不一致
这个网站的分页接口大概率是动态加载的JSON接口,而非直接返回HTML页面。你看到的带?pagenumber={page_number}的URL,可能是前端渲染用的入口,实际后端返回的是JSON数据,但你的请求没带上正确的请求头,导致服务器返回的是默认HTML页面(而非接口数据)。
解决步骤:
- 打开开发者工具「网络」标签,切换到「XHR/Fetch」分类,滚动页面加载下一页,找到对应的请求。查看该请求的完整URL、请求头、响应格式。
- 给Scrapy请求添加必要的请求头,比如模拟浏览器的
User-Agent,以及Accept: application/json来指定返回数据类型:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Accept': 'application/json, text/plain, */*' }
问题2:爬取成功但仅获取少量数据,解析失败
关于JSONDecodeError
如果确认接口返回JSON,解码错误常见原因:
- 请求未带上正确头,被重定向到HTML页面(和问题1关联)。
- 响应文本带有防注入前缀(比如
)]}),需要先清理再解析:
response_text = response.text.strip() if response_text.startswith(')]}'): response_text = response_text[3:] data = json.loads(response_text)
关于后续无新item输出
- 检查分页逻辑:确认页码起始值、上限是否正确(比如网站仅开放前N页数据),可手动请求几个页码的接口验证返回内容。
- 调整解析逻辑:JSON数据要按键值对提取,而非用CSS选择器(CSS是解析HTML的)。比如假设接口返回的新闻列表在
data['items']字段下,就遍历该字段提取数据。 - 排查反爬:请求频率过高可能被限制,在
settings.py添加DOWNLOAD_DELAY = 2设置下载延迟,或使用随机延迟。
示例代码片段
import scrapy import json class Snl24Spider(scrapy.Spider): name = 'snl24' page_number = 1 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Accept': 'application/json, text/plain, */*' } def start_requests(self): yield scrapy.Request( url=f'https://www.snl24.com/dailysun/news?pagenumber={self.page_number}', headers=self.headers, callback=self.parse ) def parse(self, response): # 处理防注入前缀 response_text = response.text.strip() if response_text.startswith(')]}'): response_text = response_text[3:] try: data = json.loads(response_text) # 按实际接口结构调整字段名 for item in data.get('items', []): yield { 'title': item.get('headline'), 'news_url': item.get('url'), 'publish_date': item.get('publishDate') } # 翻页逻辑 self.page_number += 1 # 可根据实际情况调整页码上限 if self.page_number <= 10: yield scrapy.Request( url=f'https://www.snl24.com/dailysun/news?pagenumber={self.page_number}', headers=self.headers, callback=self.parse ) except json.JSONDecodeError as e: self.logger.error(f"JSON解析错误: {str(e)}") self.logger.error(f"响应文本片段: {response.text[:500]}")
内容的提问来源于stack exchange,提问作者helloworldIwanttocode
相关产品推荐
相关产品推荐

