Scrapy CSS选择器返回空列表求助——维基词典翻译爬虫开发
解决Scrapy爬虫返回空列表的问题
嘿,我一眼就瞅出问题所在啦——你构造HtmlResponse的方式不对!
你看,HtmlResponse其实是用来创建模拟响应对象的,它本身不会主动去请求目标网页。你只传了url参数,但没有传入真实的网页HTML内容(也就是body参数),所以你的response里根本是空的,那css('ol').re(r'(?<=>)\w+(?=<)')自然抓不到任何东西,返回空列表也就不奇怪了。
而你在Scrapy Shell里能正常运行,是因为Shell会帮你实际发起网络请求,拿到了维基词典页面的真实HTML,所以选择器能匹配到内容。
修复方案:让Scrapy实际发起请求
方式1:使用标准Scrapy Spider类
这是Scrapy推荐的写法,能更好地利用框架的异步、去重等特性:
from scrapy.crawler import CrawlerProcess from scrapy.spiders import Spider class WiktionaryTranslatorSpider(Spider): name = 'wiktionary_translator' target_word = "" translation_results = [] def start_requests(self): url = f"https://en.wiktionary.org/wiki/{self.target_word}" yield self.make_requests_from_url(url) def parse(self, response): # 沿用你原来的正则提取逻辑 self.translation_results = response.css('ol').re(r'(?<=>)\w+(?=<)') print(f"翻译结果:{self.translation_results}") def scrape_translation(word): process = CrawlerProcess() WiktionaryTranslatorSpider.target_word = word process.crawl(WiktionaryTranslatorSpider) process.start() return WiktionaryTranslatorSpider.translation_results # 测试调用 scrape_translation("Hallo")
方式2:在函数中直接获取响应(适合简单场景)
如果不想写完整的Spider,也可以通过CrawlerProcess来手动获取响应:
from scrapy.http import Request from scrapy.crawler import CrawlerProcess def _fetch_response(url): """内部函数:实际发起请求获取响应""" response = None def parse_callback(res): nonlocal response response = res process.stop() # 获取到响应后停止爬虫进程 process = CrawlerProcess() process.crawl(lambda: Request(url, callback=parse_callback)) process.start() return response def scrape_translation(word): url = f"https://en.wiktionary.org/wiki/{word}" # 先获取真实的网页响应 response = _fetch_response(url) # 再执行你的提取逻辑 translation_list = response.css('ol').re(r'(?<=>)\w+(?=<)') print(translation_list) return translation_list # 测试调用 scrape_translation("Hallo")
额外提醒
- 如果你后续需要扩展功能(比如批量爬取、处理反爬、存储结果),强烈建议用方式1的Spider类写法,Scrapy的生态能帮你省很多事。
- 注意维基词典的robots协议,爬取时不要过于频繁,避免被封禁IP。
内容的提问来源于stack exchange,提问作者user5395461
相关产品推荐
相关产品推荐

