Próbuję załadować zasady XPath z bazy danych za pomocą przewijania.

Kodek, który napisałem do tej pory, jednak w porządku, jednak po pewnym debugowaniu zdałem sobie sprawę, że pisancja analizuje każdy przedmiot asynchronicznie, co oznacza, że nie mam żadnej kontroli nad kolejnością, której przedmiot jest analizowany.

Chcę to zrobić, to dowiedzieć się, który element z listy jest obecnie analizowany, gdy uderza w funkcję parse(), więc mogę odnieść się do tego indeksu do wierszy w mojej bazie danych i nabyć prawidłowe zapytanie XPath. Sposób, w jaki będę obecnie robiący, stosując zmienną o nazwie item_index i zwiększenie go po każdej iteracji przedmiotów. Teraz zdaję sobie sprawę, że to nie wystarczy i mam nadzieję, że istnieje pewna wewnętrzna funkcjonalność, która mogłaby mi pomóc.

Czy ktoś zna właściwy sposób na utrzymanie tego? Przeglądałem dokumentację, ale nie mogłem znaleźć żadnych informacji o tym. Spojrzałem również na Kod źródłowy przewiątych ale mogę Wydaje się, że dowie się, jak lista zapisów URL jest zapisywana.

Oto mój kod, aby wyjaśnić mój problem dalej:

# -*- 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

Wszelkie wskazówki byłyby bardzo doceniane!

Dzięki

3
Joel Murphy 16 sierpień 2014, 22:51

2 odpowiedzi

Najlepsza odpowiedź

Możesz przekazać indeks (lub identyfikator wierszy z bazy danych) wraz z żądaniem przy użyciu Żądanie.meta. To słownik, do którego można uzyskać dostęp z Odpowiedź.Meta w swoim przewodniku.

Na przykład, gdy budujesz prośbę:

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

Korzystanie z próby próby nie będzie działać, ponieważ nie możesz zagwarantować zamówienia, w którym odpowiedzi są obsługiwane.

1
toothrot 16 sierpień 2014, 20:57

Oto rozwiązanie, które wymyśliłem na wypadek, gdyby ktoś go potrzebuje.

Jak sugerowano @toothrot, musisz przeciążyć metody w klasie Request, aby uzyskać dostęp do informacji meta.

Mam nadzieję, że to komuś pomoże.

# -*- 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
3
Joel Murphy 16 sierpień 2014, 21:56