Scrapy爬取含指定标题卡片的对应URL时遇到问题求助
Scrapy爬取含指定标题卡片的对应URL时遇到问题求助
嘿,我来帮你梳理下问题出在哪~
首先说那个「PostsSpider.parse callback is not defined」的错误,其实你代码里明明写了parse方法,问题出在parse方法内部逻辑报错了,导致Scrapy没法正常执行这个回调,才弹出了这个有点误导性的提示。咱们一步步来修正:
1. 核心逻辑的致命错误:你循环的是文本字符串,不是DOM元素
你现在用response.css('h5.card-title::text').re(r'AZ School Safety Program')拿到的是匹配到的纯文本内容(比如"AZ School Safety Program"),而不是网页元素的选择器对象,所以后面调用card.css('base::attr(href)')肯定会炸——字符串哪来的css方法呀!
2. 正确的筛选与URL获取方式
你要的是「包含目标标题卡片的页面URL」对吧?那得先拿到所有h5.card-title元素,再筛选出文本符合要求的,然后直接取当前页面的URL就行(毕竟你的例子里,目标卡片出现在不同页面,页面URL就是你要的结果)。
3. 别忘了做全站爬取,不然只爬首页找不到其他页面的卡片
你的start_urls只有首页,但目标卡片还出现在officers、educators这类页面,所以得让Scrapy自动跟进站内所有链接,才能遍历整个站点的页面。
修正后的代码参考:
import scrapy class PostsSpider(scrapy.Spider): name = "card" start_urls = [ 'https://lawforkids.org/' ] # 把目标标题单独拎出来,方便后续修改 TARGET_TITLE = "AZ School Safety Program" def parse(self, response): # 遍历所有卡片标题元素,筛选出符合目标的 for card_title in response.css('h5.card-title'): title_text = card_title.css('::text').get(default='').strip() # 精准匹配目标标题,要忽略大小写的话可以改成title_text.lower() == self.TARGET_TITLE.lower() if title_text == self.TARGET_TITLE: yield { 'page_url': response.url, 'card_title': title_text } # 跟进所有站内链接,实现全站爬取 for href in response.css('a::attr(href)').getall(): # 把相对路径转成绝对URL absolute_url = response.urljoin(href) # 只爬取目标站点的链接,避免跑歪 if absolute_url.startswith('https://lawforkids.org/'): yield scrapy.Request(absolute_url, callback=self.parse)
额外提醒:
- 运行的时候要对应你的spider name:
scrapy crawl card,别写错成类名哦! - 如果卡片本身带独立跳转链接(不是页面URL),那你可以调整选择器,比如用
card_title.xpath('./ancestor::div[contains(@class, "card")]//a/@href').get()来获取卡片的跳转地址,具体可以根据页面实际DOM结构微调。
这样改完之后,应该就能正常爬取到所有包含目标卡片的页面URL啦~
备注:内容来源于stack exchange,提问作者caramelSuga
相关产品推荐
相关产品推荐

