Scrapy - ท่อส่งไอเทม

คำอธิบาย

Item Pipelineเป็นวิธีการประมวลผลรายการทิ้ง เมื่อไอเท็มถูกส่งไปยังท่อส่งสินค้าไอเท็มจะถูกคัดลอกโดยสไปเดอร์และประมวลผลโดยใช้ส่วนประกอบหลายอย่างซึ่งดำเนินการตามลำดับ

เมื่อใดก็ตามที่ได้รับสินค้าจะตัดสินใจดำเนินการอย่างใดอย่างหนึ่งดังต่อไปนี้ -

  • ประมวลผลรายการต่อไป
  • วางจากท่อ
  • หยุดประมวลผลรายการ

ท่อไอเทมมักใช้เพื่อวัตถุประสงค์ดังต่อไปนี้ -

  • การจัดเก็บรายการที่คัดลอกในฐานข้อมูล
  • หากได้รับไอเทมซ้ำก็จะดรอปไอเทมซ้ำ
  • จะตรวจสอบว่ารายการนั้นอยู่ในเขตข้อมูลเป้าหมายหรือไม่
  • การล้างข้อมูล HTML

ไวยากรณ์

คุณสามารถเขียน Item Pipeline โดยใช้วิธีการต่อไปนี้ -

process_item(self, item, spider)

วิธีการข้างต้นประกอบด้วยพารามิเตอร์ต่อไปนี้ -

  • Item (วัตถุสิ่งของหรือพจนานุกรม) - ระบุรายการที่คัดลอก
  • แมงมุม (วัตถุแมงมุม) - แมงมุมที่ขูดรายการ

คุณสามารถใช้วิธีการเพิ่มเติมที่ระบุในตารางต่อไปนี้ -

ซีเนียร์ No วิธีการและคำอธิบาย พารามิเตอร์
1

open_spider(self, spider)

จะถูกเลือกเมื่อแมงมุมถูกเปิดออก

แมงมุม (วัตถุแมงมุม) - หมายถึงแมงมุมที่เปิดออก

2

close_spider(self, spider)

มันถูกเลือกเมื่อแมงมุมปิด

แมงมุม (วัตถุแมงมุม) - หมายถึงแมงมุมที่ถูกปิด

3

from_crawler(cls, crawler)

ด้วยความช่วยเหลือของซอฟต์แวร์รวบรวมข้อมูลไปป์ไลน์สามารถเข้าถึงส่วนประกอบหลักเช่นสัญญาณและการตั้งค่าของ Scrapy

โปรแกรมรวบรวมข้อมูล (วัตถุโปรแกรมรวบรวมข้อมูล) - หมายถึงโปรแกรมรวบรวมข้อมูลที่ใช้ไปป์ไลน์นี้

ตัวอย่าง

ต่อไปนี้เป็นตัวอย่างของไปป์ไลน์รายการที่ใช้ในแนวคิดต่างๆ

การทิ้งรายการโดยไม่มีแท็ก

ในรหัสต่อไปนี้ไปป์ไลน์จะปรับสมดุลแอตทริบิวต์(ราคา)สำหรับสินค้าที่ไม่รวม VAT (แอตทริบิวต์ excludes_vat)และละเว้นสินค้าที่ไม่มีป้ายราคา -

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)

การเขียนรายการไปยังไฟล์ JSON

รหัสต่อไปนี้จะเก็บรายการที่คัดลอกมาจากสไปเดอร์ทั้งหมดไว้ในรายการเดียว items.jlซึ่งมีหนึ่งรายการต่อบรรทัดในรูปแบบอนุกรมในรูปแบบ JSON JsonWriterPipeline คลาสใช้ในโค้ดเพื่อแสดงวิธีการเขียนไปป์ไลน์รายการ -

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

การเขียนรายการไปยัง MongoDB

คุณสามารถระบุที่อยู่ MongoDB และชื่อฐานข้อมูลในการตั้งค่า Scrapy และคอลเลกชัน MongoDB สามารถตั้งชื่อตามคลาสไอเท็ม รหัสต่อไปนี้อธิบายถึงวิธีการใช้งานfrom_crawler() วิธีการรวบรวมทรัพยากรอย่างถูกต้อง -

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

การทำสำเนาตัวกรอง

ตัวกรองจะตรวจสอบรายการที่ซ้ำและจะปล่อยรายการที่ดำเนินการแล้ว ในรหัสต่อไปนี้เราได้ใช้ ID เฉพาะสำหรับไอเท็มของเรา แต่ Spider ส่งคืนไอเทมจำนวนมากด้วย ID เดียวกัน -

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

การเปิดใช้งานท่อส่งสินค้า

คุณสามารถเปิดใช้งานคอมโพเนนต์ไปป์ไลน์ไอเทมโดยเพิ่มคลาสในการตั้งค่าITEM_PIPELINESดังที่แสดงในโค้ดต่อไปนี้ คุณสามารถกำหนดค่าจำนวนเต็มให้กับคลาสตามลำดับที่รันได้ (ลำดับสามารถลดค่าเป็นคลาสที่มีมูลค่าสูงกว่าได้) และค่าจะอยู่ในช่วง 0-1000

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