我正在使用Scrapy从网站中提取某些价格数据。该网站的数据始终如下所示:
Amazon Price: x円
或
Search Price: x円
其中x
是不带小数部分的货币格式数字。我有一个正则表达式,用于在项目加载器中提取此字段:
loader.add_css(Product..re(r'(?<=[(Amazon Price)(Search Price)]:\s)[,\d]+(?=円)')
我从抓取的网站运行的每个测试用例都表明该正则表达式有效。在我的物品分类中,我有:
price = Field(input_processor = Compose(lambda v: print(v), Join(separator = '')),
output_processor = Compose(TakeFirst(), lambda v: print(v), lambda v: v.replace(',', ''), lambda v: int(v)),
serializer = int)
将print语句用于调试输出的地方(如果有人知道更好的方法,我很高兴听到它)。由于此字段可以从多个蜘蛛运行,其中一些蜘蛛可以将整数作为字符串的列表分配给price
,因此我正在使用Join(separator = '') to collate them in that case. I have verified that this works as well. In output, I am using
TakeFirst()to get what should be the only element on the array, removing any commas with
replace(',' ,''),并将结果转换为int
。我已经验证了所有这些代码。
现在,我问这个问题的原因:
输入处理器中的第一个print
语句仅显示[]
的值。
我检查了显示此输出的页面,并验证了它们在测试中没有这种行为。我也没有在项目中安装任何中间件,并且管道仅应在项目加载后才运行。所以,正如我机智的一面,请有人可以解释为什么会这样吗?
关于我的正则表达式的其他反馈点,因为我认为应该有更好的方法,但是还没有找到答案。
答案 0 :(得分:0)
我已解决问题,在此过程中,我发现了一些问题,我认为这些问题将帮助任何不熟悉新手的人。首先是print
实际上不返回任何内容,因此当您将其放入Compose
时,它实际上会停止执行,这是我正在做的第一个问题。
第二个问题是我试图在Spider的辅助方法之间传递loader
。这是一个问题,因为当您这样做时,项目加载器将假定您使用它创建的响应,因此使用loader.add_css
将不起作用,因为您的CSS选择器将针对您在创建项目加载器时使用的响应进行解析第一名,这可能不是您想要的。我要做的是创建一个中间件,将我所有的部分项目压缩在一起,形成一个连贯的响应。