Scrapy ItemLoader中可变长度正向后行断言正则提取尺寸值问题
解决Scrapy ItemLoader中提取Y维度尺寸的问题
不用写Pipeline,直接在ItemLoader里就能搞定,给你两个可行方案:
方案一:一次性匹配X/Y维度(推荐)
直接用一个正则同时捕获X和Y的值,再通过ItemLoader的处理器拆分到对应字段,避免前后断言的问题。
正则表达式
(\d+(?:[,.]\d+)?)\s*[xX]\s*(\d+(?:[,.]\d+)?)
这个正则会分别捕获X(第一组)和Y(第二组)的数值,兼容逗号/点作为小数分隔符,以及X/Y之间的任意空格和大小写X。
ItemLoader实现示例
from scrapy.loader import ItemLoader from scrapy.loader.processors import TakeFirst, MapCompose def extract_both_dimensions(text): import re match = re.search(r'(\d+(?:[,.]\d+)?)\s*[xX]\s*(\d+(?:[,.]\d+)?)', text) return match.groups() if match else (None, None) def normalize_decimal(val): # 把逗号分隔的小数转成点,方便后续转成数值类型 return val.replace(',', '.') if val else None class DimensionLoader(ItemLoader): default_output_processor = TakeFirst() # 提取X维度 x_dim_in = MapCompose(extract_both_dimensions) x_dim_out = lambda vals: normalize_decimal(vals[0]) if vals else None # 提取Y维度 y_dim_in = MapCompose(extract_both_dimensions) y_dim_out = lambda vals: normalize_decimal(vals[1]) if vals else None
方案二:单独匹配Y维度
如果不想一次性提取,换用负前瞻断言替代正向后行断言,匹配后面不再出现X/x的数值(也就是Y值):
正则表达式
\d+(?:[,.]\d+)?(?!.*\s*[xX]\s*)
这个正则的逻辑是:匹配符合格式的数字,且该数字之后的文本里不再有X/x,这样就能精准定位到Y维度。
ItemLoader中直接使用
from scrapy.loader import ItemLoader from scrapy.loader.processors import TakeFirst, MapCompose class DimensionLoader(ItemLoader): default_output_processor = TakeFirst() x_dim_re = r'\d+(?:[,.]\d+)?(?=\s*[xX]\s*\d+)' y_dim_re = r'\d+(?:[,.]\d+)?(?!.*\s*[xX]\s*)' # 可选:统一小数格式 x_dim_out = MapCompose(lambda x: x.replace(',', '.') if x else None) y_dim_out = MapCompose(lambda x: x.replace(',', '.') if x else None)
两种方案都能在ItemLoader内完成所有逻辑,不需要依赖Pipeline。如果后续还要做数值转换、范围校验等,也可以直接在ItemLoader的输出处理器里扩展。
内容的提问来源于stack exchange,提问作者AlexanderP
相关产品推荐
相关产品推荐

