Scrapy框架CrawlSpider未执行callback回调函数问题求助
核心问题分析
- Rule匹配顺序错误:CrawlSpider的
rules会按定义顺序匹配链接,匹配到第一条符合条件的规则后就会停止后续规则校验。你定义的第一条规则是无任何过滤条件的LinkExtractor(),会命中所有站内链接,所有带/users/的用户页链接直接被第一条规则拦截,根本不会触发第二条带parse_item回调的规则。 - 小语法问题:
allow=('/users/')写法不规范,Python中单元素元组需要加末尾逗号,否则会被识别为普通字符串而非元组,部分场景下会导致规则匹配异常。 - XPath语法错误:代码里XPath用了HTML转义字符
",实际Python代码中直接用引号嵌套即可。
修复方案
调整rules的顺序,把带回调的用户页匹配规则放在最前面,通用链接提取规则放在最后,同时规范参数写法:
import scrapy from scrapy.spiders import CrawlSpider, Rule from scrapy.linkextractors import LinkExtractor class ForumnSpider(CrawlSpider): name = 'forumn' allowed_domains = ['scratch.mit.edu'] start_urls = [ 'https://scratch.mit.edu/users/accountcraft123/' ] rules = ( # 先匹配用户个人页,触发回调,需要在用户页继续提取链接就保留follow=True Rule( LinkExtractor( allow=('/users/',), # 单元素元组加末尾逗号 ), callback='parse_item', follow=True ), # 通用链接提取规则放在最后,匹配所有没被前面规则拦截的链接 Rule( LinkExtractor(), ), ) def parse_item(self, response): self.logger.info('This is a profile page. %s', response.url) # 修复XPath的转义字符问题 username = response.xpath('//div[@class="header-text"]/h2/text()').get() yield { 'username': username, 'url': response.url }
额外注意事项
- 如果不需要爬取非用户页的其他链接,可以直接删掉最后一条通用Rule,减少不必要的请求。
- 部分scratch页面的内容是前端动态渲染的,如果XPath匹配不到数据可以检查响应源码,确认内容是否是静态返回的。
内容的提问来源于stack exchange,提问作者iL0g1c
相关产品推荐
相关产品推荐

