Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 回调之间项装入器的疑难解答_Python_Csv_Scrapy_Web Crawler - Fatal编程技术网

Python 回调之间项装入器的疑难解答

Python 回调之间项装入器的疑难解答,python,csv,scrapy,web-crawler,Python,Csv,Scrapy,Web Crawler,为了理解中的“幼稚方法”示例 我正试图复制这段代码。我们的想法是在每个字段都来自不同网站的地方填充一个项目 我试图理解为什么在运行下面的代码时会出现以下行为,并使用scrapy crawl compSpider-o prices.csv将结果导出到csv文件中 该代码实际上用相关价格填充nic_价格,但对tester_价格的填充方式不同 我认为应该这样做,因为item loader对象在请求元字段中从创建item loader对象的第一个回调[firstRequest]传递到第二个回调[pars

为了理解中的“幼稚方法”示例

我正试图复制这段代码。我们的想法是在每个字段都来自不同网站的地方填充一个项目

我试图理解为什么在运行下面的代码时会出现以下行为,并使用
scrapy crawl compSpider-o prices.csv
将结果导出到csv文件中

该代码实际上用相关价格填充nic_价格,但对tester_价格的填充方式不同

我认为应该这样做,因为item loader对象在请求元字段中从创建item loader对象的第一个回调[firstRequest]传递到第二个回调[parseDescription1],在第二个回调[parseDescription1]中item loader对象最终加载到一个item中

我已经测试了css选择器的工作。有人能帮我理解为什么我会有这种行为吗

项目申报 蜘蛛代码
css选择器是“确实可以工作”。问题存在于itemloader变量l中,您正在该变量中保存meta dict,它指向来自firstRequest回调的响应,而不是指向此css选择器可以工作的parseDescription1回调

'div.price-breakdown div.price-unclused-tax span.price::text'

要解决这个问题,只需创建一个新的itemloaderparseDescription1,或者更好地加载项目本身,而不是在元目录中加载它的加载程序,如下所示

    def firstRequest(self, response):

        l = ItemLoader(item=ProductItem(), response=response)

        l.add_css('nic_price', 'div.product-info p.product-price span[itemprop="price"]::text')

        yield Request('https://www.tester.co.uk/test-safe-pen-co-meter',
                  meta={'item': l.load_item()},
                  callback=self.parseDescription1)

    def parseDescription1(self, response):

        # Recover item
        item = response.meta['item']

        l = ItemLoader(item=ProductItem(), response=response)

        # Use just as before
        l.add_css('tester_price', 'div.price-breakdown div.price-excluding-tax span.price::text')

        l.add_value('nic_price', item['nic_price'])

        yield l.load_item()

最近,我遇到了同样的问题。尝试使用两种方法,但每种方法都有很大的缺点:

  • 传递项目加载器并使用
    add_value()
    引入了双重处理值的问题(通过输入和输出处理器),这使得设计那些使代码更难读取和维护的处理器变得更加困难

  • 传递项而不是项加载器只会扼杀项加载器的整个概念,并在整个代码中引入不一致性

  • 我在scrapy的
    scrapy.loader.ItemLoader
    源代码(非常小和简单的代码,顺便说一下)中找到的是它的
    parent
    关键字参数,它允许您传递parent ItemLoader并将其所有值复制到新的ItemLoader

    以下是修改后的
    parseDescription1

    def parseDescription1(自我,响应):
    #恢复项目(加载器)
    loader=response.meta['loader']
    如果响应。正文:
    loader=ItemLoader(item=ProductItem(),response=response,parent=loader)
    #照常使用
    tester\u loader.add\u css('tester\u price','div.price-breakdown div.price-excluding-tax span.price::text'))
    产量加载器。加载_项()
    
    scrapy crawl
    结果:

    2016-11-01 10:48:50[scrapy]调试:爬网(200)(参考:无)
    2016-11-01 10:48:50[scrapy]调试:爬网(200)(参考:无)
    2016-11-01 10:48:50[scrapy]调试:爬网(200)(参考:无)
    2016-11-01 10:48:51[scrapy]调试:爬网(200)(参考:https://www.shop.niceic.com/6559-megger-mft1711-multifunction-tester-1008-121)
    2016-11-01 10:48:51[刮伤]调试:刮伤自
    {'nic_price':[u'\xa3509.00'],
    “测试仪价格”:[u'\n\t\t\xa349.00\n\t\t']}
    
    我的程序的目标是通过从不同站点获取每个属性来生成项目。我试图实现您的代码,但随后我分别生成了“l”和“l2”项加载器,这将产生两个项。我正在研究一种解决方法,欢迎提供任何帮助。解决此问题的方法有很多,一种简单的方法是在meta
    meta={'item':l.load_item(),
    then中加载项本身,而不是它的加载器,在parseDescription1中,从元目录中获取项目并将nic_价格作为值添加到
    item=response.meta['item']
    l.add_值('nic_价格',item['nic_价格])
    我最终传递的是项目,而不是项目加载器。在每个链式解析函数中,我都添加了项的一个属性。我刚刚发现用新的变量覆盖加载器变量更好。也仅当响应有
    主体
    成员时才执行此操作。有点编辑代码。我得到一个错误:
    keyrerror:
    loader=response.meta['loader']
    上使用Scrapy 1.4.0的“loader'
    import scrapy
    from scrapy.http import Request
    from scrapy.loader import ItemLoader
    from comparator.items import ProductItem
    
    
    class Compspider(scrapy.Spider):
        name = "compSpider"
    
    
        #start_urls = (  'https://www.shop.niceic.com/',   )
    
        def start_requests(self):  
    
            yield Request(
                'https://www.shop.niceic.com/6559-megger-mft1711-multifunction-tester-1008-121',  callback=self.firstRequest)
    
    
        def firstRequest(self, response):
            l = ItemLoader(item=ProductItem(), response=response)
            l.add_css('nic_price', 'div.product-info p.product-price span[itemprop="price"]::text')
    
            yield Request('https://www.tester.co.uk/test-safe-pen-co-meter', meta={'loader' : l}, callback= self.parseDescription1)
    
        def parseDescription1(self, response):
    
            # Recover item(loader)
            l = response.meta['loader']
    
            # Use just as before
            l.add_css('tester_price', 'div.price-breakdown div.price-excluding-tax span.price::text')
    
            yield l.load_item()
    
        def firstRequest(self, response):
    
            l = ItemLoader(item=ProductItem(), response=response)
    
            l.add_css('nic_price', 'div.product-info p.product-price span[itemprop="price"]::text')
    
            yield Request('https://www.tester.co.uk/test-safe-pen-co-meter',
                      meta={'item': l.load_item()},
                      callback=self.parseDescription1)
    
        def parseDescription1(self, response):
    
            # Recover item
            item = response.meta['item']
    
            l = ItemLoader(item=ProductItem(), response=response)
    
            # Use just as before
            l.add_css('tester_price', 'div.price-breakdown div.price-excluding-tax span.price::text')
    
            l.add_value('nic_price', item['nic_price'])
    
            yield l.load_item()