使用Scrapy爬取Ask搜索结果时输出空文件的解决方法
Scrapy爬取Ask搜索结果导出文件为空的问题修复
问题根因
- 响应解析逻辑完全不匹配:你参考的Google SERP爬取教程针对的是返回JSON格式数据的接口,但Ask搜索的
https://www.ask.com/web?q=路径返回的是标准HTML页面,代码中直接调用json.loads(response.text)会直接抛出解析异常,中断整个parse函数执行,根本不会执行到yield item的步骤,最终导出的json文件为空。 - 元素提取方式错误:你直接把CSS选择器字符串当做JSON键值去取数据,HTML页面的内容必须通过Scrapy的CSS/XPath选择器提取,不存在你写的
di['organic_results']这类JSON字段。 - 逻辑缩进错误:翻页请求的判断逻辑写在了搜索结果遍历循环的内部,会导致每遍历一条结果就重复触发翻页请求,逻辑完全混乱。
- 默认请求配置触发反爬:Scrapy默认的User-Agent带有明显爬虫标识,且默认遵守robots协议,Ask会拦截这类请求返回错误页,和你之前看到的HttpErrorMiddleware日志对应。
修复后可运行代码
import scrapy from datetime import datetime class PagesearchSpider(scrapy.Spider): name = 'pageSearch' # 补充基础配置绕过基础反爬 custom_settings = { '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', 'ROBOTSTXT_OBEY': False, 'HTTPERROR_ALLOWED_CODES': [200] } def start_requests(self): queries = ['love'] for query in queries: url = 'https://www.ask.com/web?q=' + query yield scrapy.Request(url, callback=self.parse, meta={'pos': 0}) def parse(self, response): # 调试用:确认返回内容是正常搜索页而非反爬拦截页 # print(response.text) pos = response.meta['pos'] dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 遍历所有搜索结果项 for result in response.css('.PartialSearchResults-item'): item = { 'title': result.css('a.PartialSearchResults-item-title-link.result-link::text').get('').strip(), 'snippet': result.css('p.PartialSearchResults-item-abstract::text').get('').strip(), 'link': result.css('a.PartialSearchResults-item-title-link.result-link::attr(href)').get(''), 'position': pos, 'date': dt } pos += 1 yield item # 翻页逻辑移到循环外,正确提取下一页链接 next_page = response.css('.PartialWebPagination-next::attr(href)').get() if next_page: yield scrapy.Request(next_page, callback=self.parse, meta={'pos': pos})
运行注意事项
- 运行前先删除目录下之前生成的空
test.json文件,避免历史文件干扰 - 运行命令保持不变:
scrapy crawl pageSearch -o test.json - 如果终端打印的response.text出现验证码、访问拦截提示,需要额外补充请求头、增加下载延迟或者配置代理
内容的提问来源于stack exchange,提问作者keni
相关产品推荐
相关产品推荐

