Scrapy - rurociąg z przedmiotami

Opis

Item Pipelineto metoda, w której przetwarzane są złomowane elementy. Gdy przedmiot jest wysyłany do rurociągu przedmiotów, jest zeskrobywany przez pająka i przetwarzany przy użyciu kilku komponentów, które są wykonywane sekwencyjnie.

Za każdym razem, gdy otrzyma przedmiot, podejmuje decyzję o jednej z następujących czynności -

  • Kontynuuj przetwarzanie pozycji.
  • Zrzuć to z rurociągu.
  • Zatrzymaj przetwarzanie pozycji.

Potoki pozycji są zwykle używane do następujących celów -

  • Przechowywanie pobranych elementów w bazie danych.
  • Jeśli otrzymany element zostanie powtórzony, porzuci powtarzający się element.
  • Sprawdza, czy element zawiera pola docelowe.
  • Czyszczenie danych HTML.

Składnia

Możesz napisać plan pozycji za pomocą następującej metody -

process_item(self, item, spider)

Powyższa metoda zawiera następujące parametry -

  • Pozycja (obiekt lub słownik) - określa zeskrobany element.
  • pająk (obiekt pająka) - Pająk, który zeskrobał przedmiot.

Możesz użyć dodatkowych metod podanych w poniższej tabeli -

Sr.No Metoda i opis Parametry
1

open_spider(self, spider)

Jest wybierany, gdy pająk jest otwarty.

pająk (obiekt pająka) - odnosi się do pająka, który został otwarty.

2

close_spider(self, spider)

Jest wybierany, gdy pająk jest zamknięty.

pająk (obiekt pająka) - Odnosi się do pająka, który został zamknięty.

3

from_crawler(cls, crawler)

Z pomocą robota, potok może uzyskać dostęp do podstawowych komponentów, takich jak sygnały i ustawienia Scrapy.

robot indeksujący (obiekt robota) - odnosi się do robota używającego tego potoku.

Przykład

Poniżej przedstawiono przykłady potoku pozycji używanego w różnych koncepcjach.

Upuszczanie przedmiotów bez tagu

W poniższym kodzie potok równoważy atrybut (cena) dla tych produktów, które nie zawierają podatku VAT (atrybut excludes_vat) i ignoruje te produkty, które nie mają metki z ceną -

from Scrapy.exceptions import DropItem  
class PricePipeline(object): 
   vat = 2.25 

   def process_item(self, item, spider): 
      if item['price']: 
         if item['excludes_vat']: 
            item['price'] = item['price'] * self.vat 
            return item 
         else: 
            raise DropItem("Missing price in %s" % item)

Zapisywanie elementów do pliku JSON

Poniższy kod przechowuje wszystkie zeskrobane elementy wszystkich pająków w jednym items.jlplik, który zawiera po jednym elemencie na wiersz w postaci serializowanej w formacie JSON. PlikJsonWriterPipeline klasa jest używana w kodzie, aby pokazać, jak pisać potok elementów -

import json  

class JsonWriterPipeline(object): 
   def __init__(self): 
      self.file = open('items.jl', 'wb') 

   def process_item(self, item, spider): 
      line = json.dumps(dict(item)) + "\n" 
      self.file.write(line) 
      return item

Pisanie elementów do MongoDB

Możesz określić adres MongoDB i nazwę bazy danych w ustawieniach Scrapy, a kolekcja MongoDB może zostać nazwana zgodnie z klasą elementu. Poniższy kod opisuje, jak używaćfrom_crawler() sposób prawidłowego gromadzenia zasobów -

import pymongo  

class MongoPipeline(object):  
   collection_name = 'Scrapy_list' 

   def __init__(self, mongo_uri, mongo_db): 
      self.mongo_uri = mongo_uri 
      self.mongo_db = mongo_db 

   @classmethod 
   def from_crawler(cls, crawler): 
      return cls( 
         mongo_uri = crawler.settings.get('MONGO_URI'), 
         mongo_db = crawler.settings.get('MONGO_DB', 'lists') 
      ) 
  
   def open_spider(self, spider): 
      self.client = pymongo.MongoClient(self.mongo_uri) 
      self.db = self.client[self.mongo_db] 

   def close_spider(self, spider): 
      self.client.close() 

   def process_item(self, item, spider): 
      self.db[self.collection_name].insert(dict(item)) 
      return item

Powielanie filtrów

Filtr sprawdzi powtarzające się pozycje i usunie już przetworzone pozycje. W poniższym kodzie użyliśmy unikalnego identyfikatora dla naszych produktów, ale pająk zwraca wiele elementów o tym samym identyfikatorze -

from scrapy.exceptions import DropItem  

class DuplicatesPipeline(object):  
   def __init__(self): 
      self.ids_seen = set() 

   def process_item(self, item, spider): 
      if item['id'] in self.ids_seen: 
         raise DropItem("Repeated items found: %s" % item) 
      else: 
         self.ids_seen.add(item['id']) 
         return item

Aktywacja potoku pozycji

Można aktywować składnik potoku pozycji, dodając jego klasę do ustawienia ITEM_PIPELINES , jak pokazano w poniższym kodzie. Możesz przypisać wartości całkowite do klas w kolejności, w jakiej działają (kolejność może mieć niższą wartość do klas o wyższej wartości), a wartości będą w zakresie 0-1000.

ITEM_PIPELINES = {
   'myproject.pipelines.PricePipeline': 100,
   'myproject.pipelines.JsonWriterPipeline': 600,
}