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
2 odpowiedzi
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.
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
Podobne pytania
Nowe pytania
python
Python to wielozadaniowy, wielozadaniowy język programowania dynamicznie typowany. Został zaprojektowany tak, aby był szybki do nauczenia się, zrozumienia i użycia oraz wymuszania czystej i jednolitej składni. Należy pamiętać, że Python 2 oficjalnie nie jest obsługiwany od 01-01-2020. Mimo to, w przypadku pytań Pythona specyficznych dla wersji, dodaj znacznik [python-2.7] lub [python-3.x]. Korzystając z wariantu Pythona (np. Jython, PyPy) lub biblioteki (np. Pandas i NumPy), należy umieścić go w tagach.