通过 scrapy itemloader 传递一个选择器

pass a selector through scrapy itemloader

所以在抓取时,我正在寻找一个元素,它是 html 代码中两个不同元素的组合。我正在考虑使用 scrapy 的 ItemLoaders 来摆脱这可能产生的丑陋代码。要到达元素,可以使用以下选择器:

main_element = response.css('css_to_main')
element_one = main_element.css('css_to_one::text').get()
element_two = main_element.css('css_to_two::text').get()
final_element = element_one + element_two # (with some extra processing one both elements)

为了达到预期的效果,我首先传递 main_element:

l = MyLoader(MyItem(), selector=response)
l.add_css('variable_name','css_to_main')

然后通过加载程序

class MyLoader(ItemLoader):
    variable_name_in = Combine()
    variable_name_out = Identity()

class Combine:
    def __call__(self,values):
        main_element = values[0]
        first_element = main_element.css('span.css_to_one::text').get()
        second_element = main_element.css('span.css_to_two::text').get()
        return [first_element, second_element]

想法是,它然后被传递给项目:

class MyItem(scrapy.Item):
    variable_name = scrapy.Field(
                              input_processor = MapCompose(remove_tags, strip_content),
                              output_processor = Join('')
)

但是,这个方法行不通。我似乎无法弄清楚 .add_css 方法如何将给定值传递给加载程序等等,有没有人知道如何为 Scrapy 中的项目构造这样的处理?

使用 itemloader 是正确的方法。按顺序传递两个选择器,然后使用输出处理器将它们连接起来。默认的Itemloader就可以达到目的

from scrapy.loader import ItemLoader
from itemloaders.processors import Join

l = ItemLoader(MyItem(), response=response, selector=response.css('css_to_main'))
l.add_css('variable_name','css_to_one::text')
l.add_css('variable_name','css_to_two::text')
yield l.load_item()

然后在项目字段中使用输入和输出处理器处理这些值。为了简单起见,我省略了输入处理器。但您可以根据需要添加它们。

class MyItem(scrapy.Item):
    variable_name = scrapy.Field(output_processor = Join(''))