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,
}