【问题标题】:How to get url and row id from database before scraping to use it in pipeline to store data?如何在抓取之前从数据库中获取 url 和 row id 以在管道中使用它来存储数据?
【发布时间】:2021-06-10 20:08:44
【问题描述】:

我正在尝试制作一个蜘蛛,它可以从数据库中获取一些过时的 url,对其进行解析并更新数据库中的数据。我需要获取 scrape 的 url 和 ids 以使用它保存抓取数据的管道。

我编写了这段代码,但我不知道为什么 scrapy 会更改抓取链接的顺序,看起来像是随机的,所以我的代码分配了 ids 错误。如何为每个链接分配 id?

   def start_requests(self):
        urls = self.get_urls_from_database()
        # urls looks like [('link1', 1), ('link2', 2), ('link3', 3)]
        for url in urls:
            # url ('link1', 1)
            self.links_ids.append(url[1])
            yield scrapy.Request(url=url[0], callback=self.parse, dont_filter=True)

    def get_urls_from_database(self):
        self.create_connection()
        self.dbcursor.execute("""SELECT link, id FROM urls_table""")
        urls = self.dbcursor.fetchall()
        return urls

    def parse(self, response):
        item = ScrapyItem()
        link_id = self.links_ids[0]
        self.links_ids.remove(link_id)

        ...

        item['name'] = name
        item['price'] = price
        item['price_currency'] = price_currency
        item['link_id'] = link_id

        yield item

由于未按顺序处理链接,因此将输出分配给数据库中的错误项目: 第1项的名称保存为第3项的名称,第8项的价格为第1项的价格等等。

【问题讨论】:

    标签: python python-3.x scrapy


    【解决方案1】:

    异步

    Scrapy 似乎正在异步调度 GET。

    您的代码没有很好地处理这个问题。

    命名

    你从数据库中得到的不是urls, 而是rowspairs

    而不是写:

            for url in urls:
    

    并使用[0][1] 下标, 解压这两个项目会更pythonic:

            for url, id in pairs:
    

    网址→id

    您尝试以这种方式恢复 ID:

            link_id = self.links_ids[0]
    

    考虑将 DB 结果存储在 dict 而不是list:

            for url, id in pairs:
                self.url_to_id[url] = id
    

    然后您可以稍后查找所需的 ID link_id = self.url_to_id[url]

    迭代

    好的,让我们看看这个循环中发生了什么:

        for url in urls:
            self.links_ids.append(url[1])
            yield scrapy.Request(url=url[0], callback=self.parse, dont_filter=True)
    

    在那个循环中,你最终会运行这一行:

            self.links_ids.remove(link_id)
    

    您似乎正在尝试使用 list,有零个或一个元素, 作为标量变量, 至少在 Scrapy 同步运行的环境中。 这是一个奇怪的用法。使用例如我建议的dict 可能会让你更快乐。

    此外,您的代码假定回调会发生 按他们入队的顺序; 不是这种情况。 dict 会为您解决这个难题。

    【讨论】:

    • 像魅力一样工作。谢谢你:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多