【问题标题】:Scrapy - Get index of item being parsed?Scrapy - 获取正在解析的项目的索引?
【发布时间】:2014-10-10 03:49:08
【问题描述】:

我正在尝试使用 Scrapy 从数据库中加载一些 XPATH 规则。

到目前为止,我编写的代码运行良好,但是经过一些调试后,我意识到 Scrapy 正在异步解析每个项目,这意味着我无法控制正在解析的项目的顺序。

我想要做的是找出列表中的哪个项目在遇到parse() 函数时正在被解析,这样我就可以将该索引引用到我的数据库中的行并获取正确的 XPATH 查询。我目前这样做的方式是使用一个名为item_index 的变量,并在每次项目迭代后递增它。现在我意识到这还不够,我希望有一些内部功能可以帮助我实现这一目标。

有谁知道跟踪这个的正确方法吗?我浏览了文档,但找不到任何有关它的信息。我还查看了Scrapy source code,但我似乎无法弄清楚 URL 列表的实际存储方式。

这是我的代码以进一步解释我的问题:

# -*- coding: utf-8 -*-

from scrapy.spider import Spider
from scrapy.selector import Selector

from dirbot.items import Product

from dirbot.database import DatabaseConnection

# Create a database connection object so we can execute queries
connection = DatabaseConnection()

class DmozSpider(Spider):
    name = "dmoz"
    start_urls = []
    item_index = 0

    # Query for all products sold by a merchant
    rows = connection.query("SELECT * FROM products_merchant WHERE 1=1")

    def start_requests(self):
        for row in self.rows:
            yield self.make_requests_from_url(row["product_url"])

    def parse(self, response):
        sel = Selector(response)
        item = Product()
        item['product_id'] = self.rows[self.item_index]['product_id']
        item['merchant_id'] = self.rows[self.item_index]['merchant_id']
        item['price'] = sel.xpath(self.rows[self.item_index]['xpath_rule']).extract()

        self.item_index+=1

        return item

任何指导将不胜感激!

谢谢

【问题讨论】:

    标签: python database xpath web-scraping scrapy


    【解决方案1】:

    您可以使用Request.meta 将索引(或数据库中的行ID)与请求一起传递。这是您可以在处理程序中从Response.meta 访问的字典。

    例如,当您构建请求时:

    Request(url, callback=self.some_handler, meta={'row_id': row['id']})

    使用您尝试过的计数器是行不通的,因为您无法保证处理响应的顺序。

    【讨论】:

    • 感谢您的帮助!这引导我找到解决方案:)
    • 当然。此外,您可能只想传递整个行对象本身,而不是索引(因为您在示例中只使用索引来访问行对象)。
    【解决方案2】:

    这是我想出的解决方案,以防万一有人需要。

    正如@toothrot 建议的那样,您需要重载Request 类中的方法才能访问meta 信息。

    希望这对某人有所帮助。

    # -*- coding: utf-8 -*-
    
    from scrapy.spider import Spider
    from scrapy.selector import Selector
    from scrapy.http import Request
    
    from dirbot.items import Product
    
    from dirbot.database import DatabaseConnection
    
    # Create a database connection object so we can execute queries
    connection = DatabaseConnection()
    
    class DmozSpider(Spider):
        name = "dmoz"
        start_urls = []
    
        # Query for all products sold by a merchant
        rows = connection.query("SELECT * FROM products_merchant WHERE 1=1")
    
        def start_requests(self):
            for indx, row in enumerate(self.rows):
                self.start_urls.append( row["product_url"] )
                yield self.make_requests_from_url(row["product_url"], {'index': indx})
    
        def make_requests_from_url(self, url, meta):
           return Request(url, callback=self.parse, dont_filter=True, meta=meta)
    
        def parse(self, response):
    
            item_index = response.meta['index']
    
            sel = Selector(response)
            item = Product()
            item['product_id'] = self.rows[item_index]['product_id']
            item['merchant_id'] = self.rows[item_index]['merchant_id']
            item['price'] = sel.xpath(self.rows[item_index]['xpath_rule']).extract()
    
            return item
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-03
      相关资源
      最近更新 更多