Как получить URL-адрес и идентификатор строки из базы данных, прежде чем использовать ее в конвейере для хранения данных? - PullRequest
1 голос
/ 08 мая 2019

Я пытаюсь создать паука, который получает устаревшие URL-адреса из базы данных, анализирует их и обновляет данные в базе данных.Мне нужно получить URL-адреса для списков и идентификаторы, чтобы использовать их конвейер, который сохраняет извлеченные данные.

Я создал этот код, но я не знаю, почему Scrap меняет порядок очищенных ссылок, выглядит как случайный,поэтому мой код неверно идентифицирует код.Как я могу присвоить идентификатор для каждой ссылки?

   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 и т. Д.

1 Ответ

1 голос
/ 08 мая 2019

async

Кажется, что Scrapy выполняет асинхронное планирование GET.

Ваш код с этим не справляется.

Именование

Что вы получаете отБД не urls, а скорее rows или pairs.

Вместо записи:

        for url in urls:

и использования [0] или [1] подписок, было быбудь более питоническим, чтобы распаковать два предмета:

        for url, id in pairs:

url → id

Вы пытаетесь восстановить идентификатор следующим образом:

        link_id = self.links_ids[0]

Рассмотрите возможность сохранения результатов БДв dict, а не list:

        for url, id in pairs:
            self.url_to_id[url] = 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, которое я предложил, вероятно, сделает вас счастливее.

Кроме того, ваш код предполагает, что обратные вызовы будут происходить в той последовательности, в которой они были поставлены в очередь;это не вариант.A dict решит эту проблему для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...