Scrapy中Xpath检索到的列表元素未正确逐项输出(for,yield)

1qczuiv0  于 2022-11-09  发布在  其他
关注(0)|答案(1)|浏览(137)

我将从特定EC站点提取的参展商订单结果页面第一页的URL输出到csv文件,在start_requests中阅读它,并使用for语句循环访问它。
每个订单结果页面包含30种产品的信息。
https://www.buyma.com/buyer/2597809/sales_1.html
itempage
为每个订单结果页面上的30个项目指定链接,并指定list?类型,我尝试逐个检索它们并将它们存储在项目中,如下面的代码所示,但它不起作用。

class AllSaledataSpider(CrawlSpider):
name = 'all_salesdata_copy2'
allowed_domains = ['www.buyma.com']

def start_requests(self):
     with open('/Users/morni/researchtool/AllshoppersURL.csv', 'r', encoding='utf-8-sig') as f:
        reader = csv.reader(f)
        for row in reader:
            for n in range(1, 300): 
                url =str((row[2])[:-5]+'/sales_'+str(n)+'.html')
                yield scrapy.Request(
                    url=url,
                    callback=self.parse_firstpage_item,
                    dont_filter=True
                    )

def parse_firstpage_item(self, response): 
        loader = ItemLoader(item = ResearchtoolItem(), response = response)

        Conversion_date = response.xpath('//*[@id="buyeritemtable"]/div/ul/li[2]/p[3]/text()').getall()
        product_name = response.xpath('//*[@id="buyeritemtable"]/div/ul/li[2]/p[1]/a/text()').getall()
        product_URL = response.xpath('//*[@id="buyeritemtable"]/div/ul/li[2]/p[1]/a/@href').getall()

        for i in range(30):
            loader.add_value("Conversion_date", Conversion_date[i])
            loader.add_value("product_name", product_name[i])
            loader.add_value("product_URL", product_URL[i])

            yield loader.load_item()

为每个订单结果页面上的30个项目指定链接,并指定list?类型,我尝试逐个检索它们并将它们存储在项目中,如下面的代码所示,但它不起作用。
输出如下所示,其中每个项目一次包含多个信息项目。
当前状态:{"product_name": ["product1", "product2"]), "Conversion_date":["Conversion_date1", "Conversion_date2" ], "product_URL":["product_URL1", "product_URL2"]},
理想值:[{"product_name": "product1", "Conversion_date": Conversion_date1", "product_URL": "product_URL1"},{"product_name": "product2", "Conversion_date": Conversion_date2", "product_URL": "product_URL2"}]
这可能是由于我对语句的基本理解不足而产生的。

vdzxcuhz

vdzxcuhz1#

每次迭代都需要创建一个新的加载程序

for i in range(30):
    loader = ItemLoader(item = ResearchtoolItem(), response = response)
    loader.add_value("Conversion_date", Conversion_date[i])
    loader.add_value("product_name", product_name[i])
    loader.add_value("product_URL", product_URL[i])

    yield loader.load_item()

编辑:

add_value将一个值添加到列表中。由于列表中没有元素,所以添加后列表中只有一个元素。
要获取字符串形式的值,可以使用处理器。例如:

import scrapy
from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst

class ProductItem(scrapy.Item):
    name = scrapy.Field(output_processor=TakeFirst())
    price = scrapy.Field(output_processor=TakeFirst())

class ExampleSpider(scrapy.Spider):
    name = 'exampleSpider'
    start_urls = ['https://scrapingclub.com/exercise/list_infinite_scroll/']

    def parse(self, response,**kwargs):
        names = response.xpath('//div[@class="card-body"]//h4/a/text()').getall()
        prices = response.xpath('//div[@class="card-body"]//h5//text()').getall()
        length = len(names)

        for i in range(length):
            loader = ItemLoader(item=ProductItem(), response=response)
            loader.add_value('name', names[i])
            loader.add_value('price', prices[i])

            yield loader.load_item()

相关问题