Scrapy中XPath提取子串报错及电影年份提取方案咨询
解决Scrapy爬取电影年份的XPath问题及实用方法
嘿,我来帮你搞定这个爬取电影年份的问题!你遇到的XPath语法错误,大概率是踩了这几个常见的坑:
一、XPath提取括号内日期出错的常见原因
- 特殊场景下的文本获取问题:很多时候标题和日期所在的元素会包含多个子节点(比如
<div><span>电影名</span>(2023)</div>),直接用text()只能拿到子节点外的零散文本,导致后续的字符串函数找不到括号位置,进而触发语法或匹配错误。 - 函数嵌套或参数错误:比如使用
substring-before/substring-after时参数顺序搞反,或者没有用normalize-space()处理文本里的空格、换行,导致括号的匹配位置偏移。 - 多括号干扰:如果电影名本身带有括号(比如《蜘蛛侠(平行宇宙)》(2018)),纯XPath字符串函数会优先匹配第一个左括号,提取出错误内容,看起来像是语法报错,但实际是逻辑问题。
二、提取电影出品年份的实用方法
1. 正则表达式 + XPath(最灵活推荐)
Scrapy的Selector支持直接结合re()方法,比纯XPath字符串函数更能应对复杂文本场景:
# 方式1:直接用XPath定位元素后调用正则提取 year = response.xpath('//div[@class="movie-item"]/h3/text()').re(r'\((\d{4})\)')[0] # 方式2:先获取完整元素文本再正则匹配(应对多子节点情况) full_title_text = response.xpath('string(//div[@class="movie-title"])').get() year = re.search(r'\((\d{4})\)', full_title_text).group(1)
这个方法能自动忽略电影名里的括号,精准提取4位数字的年份。
2. 修正后的纯XPath方案
如果坚持用纯XPath,记得先获取完整元素文本再处理:
# 先标准化文本(去除多余空格换行),再提取括号内内容 year = response.xpath('substring-before(substring-after(normalize-space(//div[@class="movie-title"]), "("), ")")').get()
注意:这个方法只适合每个元素只有一对年份括号的场景,电影名带括号时会失效。
3. 直接定位年份独立节点(最精准)
如果页面把年份单独放在了某个子节点里(比如<span class="year">(2023)</span>),直接提取这个节点的文本最稳妥:
year = response.xpath('//span[@class="year"]/text()').get().strip('()')
4. 用Item Loader拆分处理(适合批量爬取)
如果需要同时提取标题和年份并分开存储,用Scrapy的Item Loader会让代码更清晰:
from scrapy.loader import ItemLoader from scrapy.loader.processors import TakeFirst, MapCompose import re def extract_year(text): match = re.search(r'\((\d{4})\)', text) return match.group(1) if match else None def clean_title(text): return re.sub(r'\(\d{4}\)', '', text).strip() loader = ItemLoader(item=MovieItem(), response=response) loader.add_xpath('title', '//div[@class="movie-title"]/text()', MapCompose(clean_title), TakeFirst()) loader.add_xpath('year', '//div[@class="movie-title"]/text()', MapCompose(extract_year), TakeFirst()) movie_item = loader.load_item()
内容的提问来源于stack exchange,提问作者vforbiedronka
相关产品推荐
相关产品推荐

