Scrapy - Máy xúc vật phẩm
Sự miêu tả
Trình tải vật phẩm cung cấp một cách thuận tiện để lấp đầy các vật phẩm được lấy từ các trang web.
Khai báo Máy xúc vật phẩm
Việc khai báo Máy xúc vật phẩm giống như các Vật phẩm.
Ví dụ -
from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst, MapCompose, Join
class DemoLoader(ItemLoader):
default_output_processor = TakeFirst()
title_in = MapCompose(unicode.title)
title_out = Join()
size_in = MapCompose(unicode.strip)
# you can continue scraping here
Trong đoạn mã trên, bạn có thể thấy rằng bộ xử lý đầu vào được khai báo bằng _in hậu tố và bộ xử lý đầu ra được khai báo bằng cách sử dụng _out hậu tố.
Các ItemLoader.default_input_processor và ItemLoader.default_output_processor các thuộc tính được sử dụng để khai báo bộ xử lý đầu vào / đầu ra mặc định.
Sử dụng máy xúc vật phẩm để điền vật phẩm
Để sử dụng Trình tải mục, trước tiên hãy khởi tạo đối tượng giống như dict hoặc không có đối tượng mà mục sử dụng lớp Mục được chỉ định trong ItemLoader.default_item_class thuộc tính.
Bạn có thể sử dụng bộ chọn để thu thập các giá trị vào Trình tải vật phẩm.
Bạn có thể thêm nhiều giá trị hơn trong cùng một trường mục, trong đó Trình tải mục sẽ sử dụng một trình xử lý thích hợp để thêm các giá trị này.
Đoạn mã sau minh họa cách các mục được điền bằng cách sử dụng Máy xúc vật phẩm -
from scrapy.loader import ItemLoader
from demoproject.items import Demo
def parse(self, response):
l = ItemLoader(item = Product(), response = response)
l.add_xpath("title", "//div[@class = 'product_title']")
l.add_xpath("title", "//div[@class = 'product_name']")
l.add_xpath("desc", "//div[@class = 'desc']")
l.add_css("size", "div#size]")
l.add_value("last_updated", "yesterday")
return l.load_item()
Như được hiển thị ở trên, có hai XPath khác nhau mà từ đó title trường được trích xuất bằng cách sử dụng add_xpath() phương pháp -
1. //div[@class = "product_title"]
2. //div[@class = "product_name"]
Sau đó, một yêu cầu tương tự được sử dụng cho desccánh đồng. Dữ liệu kích thước được trích xuất bằng cách sử dụngadd_css() phương pháp và last_updated được điền bằng giá trị "hôm qua" bằng cách sử dụng add_value() phương pháp.
Sau khi tất cả dữ liệu được thu thập, hãy gọi ItemLoader.load_item() phương thức trả về các mục chứa đầy dữ liệu được trích xuất bằng add_xpath(), add_css() và add_value() các phương pháp.
Bộ xử lý đầu vào và đầu ra
Mỗi trường của Trình tải mục chứa một bộ xử lý đầu vào và một bộ xử lý đầu ra.
Khi dữ liệu được trích xuất, bộ xử lý đầu vào sẽ xử lý nó và kết quả của nó được lưu trữ trong ItemLoader.
Tiếp theo, sau khi thu thập dữ liệu, hãy gọi phương thức ItemLoader.load_item () để lấy đối tượng Item đã được phổ biến.
Cuối cùng, bạn có thể gán kết quả của bộ xử lý đầu ra cho mục.
Đoạn mã sau trình bày cách gọi bộ xử lý đầu vào và đầu ra cho một trường cụ thể:
l = ItemLoader(Product(), some_selector)
l.add_xpath("title", xpath1) # [1]
l.add_xpath("title", xpath2) # [2]
l.add_css("title", css) # [3]
l.add_value("title", "demo") # [4]
return l.load_item() # [5]
Line 1 - Dữ liệu của tiêu đề được trích xuất từ xpath1 và được chuyển qua bộ xử lý đầu vào và kết quả của nó được thu thập và lưu trữ trong ItemLoader.
Line 2 - Tương tự, tiêu đề được trích xuất từ xpath2 và được chuyển qua cùng một bộ xử lý đầu vào và kết quả của nó được thêm vào dữ liệu được thu thập cho [1].
Line 3 - Tiêu đề được trích xuất từ bộ chọn css và được chuyển qua cùng một bộ xử lý đầu vào và kết quả được thêm vào dữ liệu được thu thập cho [1] và [2].
Line 4 - Tiếp theo, giá trị "demo" được gán và chuyển qua các bộ xử lý đầu vào.
Line 5 - Cuối cùng, dữ liệu được thu thập nội bộ từ tất cả các trường và chuyển đến bộ xử lý đầu ra và giá trị cuối cùng được gán cho Item.
Khai báo bộ xử lý đầu vào và đầu ra
Các bộ xử lý đầu vào và đầu ra được khai báo trong định nghĩa ItemLoader. Ngoài điều này, chúng cũng có thể được chỉ định trongItem Field metadata.
Ví dụ -
import scrapy
from scrapy.loader.processors import Join, MapCompose, TakeFirst
from w3lib.html import remove_tags
def filter_size(value):
if value.isdigit():
return value
class Item(scrapy.Item):
name = scrapy.Field(
input_processor = MapCompose(remove_tags),
output_processor = Join(),
)
size = scrapy.Field(
input_processor = MapCompose(remove_tags, filter_price),
output_processor = TakeFirst(),
)
>>> from scrapy.loader import ItemLoader
>>> il = ItemLoader(item = Product())
>>> il.add_value('title', [u'Hello', u'<strong>world</strong>'])
>>> il.add_value('size', [u'<span>100 kg</span>'])
>>> il.load_item()
Nó hiển thị đầu ra là -
{'title': u'Hello world', 'size': u'100 kg'}
Bối cảnh trình tải vật phẩm
Ngữ cảnh trình tải mục là một mệnh lệnh của các giá trị khóa tùy ý được chia sẻ giữa các bộ xử lý đầu vào và đầu ra.
Ví dụ: giả sử bạn có một hàm parse_length -
def parse_length(text, loader_context):
unit = loader_context.get('unit', 'cm')
# You can write parsing code of length here
return parsed_length
Bằng cách nhận các đối số loader_context, nó cho Trình tải vật phẩm biết rằng nó có thể nhận ngữ cảnh Trình tải vật phẩm. Có một số cách để thay đổi giá trị của ngữ cảnh Trình tải vật phẩm -
Sửa đổi ngữ cảnh Trình tải mục đang hoạt động hiện tại -
loader = ItemLoader (product)
loader.context ["unit"] = "mm"
Khi khởi tạo Trình tải mục -
loader = ItemLoader(product, unit = "mm")
Trên khai báo Trình tải vật phẩm cho các bộ xử lý đầu vào / đầu ra khởi tạo với ngữ cảnh Trình tải vật phẩm -
class ProductLoader(ItemLoader):
length_out = MapCompose(parse_length, unit = "mm")
Đối tượng ItemLoader
Nó là một đối tượng trả về một trình tải mục mới để điền vào mục đã cho. Nó có lớp sau:
class scrapy.loader.ItemLoader([item, selector, response, ]**kwargs)
Bảng sau đây cho thấy các tham số của các đối tượng ItemLoader:
Sr.No | Mô tả về Thông Số |
---|---|
1 | item Đây là mục cần điền bằng cách gọi add_xpath (), add_css () hoặc add_value (). |
2 | selector Nó được sử dụng để trích xuất dữ liệu từ các trang web. |
3 | response Nó được sử dụng để xây dựng bộ chọn bằng default_selector_class. |
Bảng sau cho thấy các phương thức của các đối tượng ItemLoader:
Sr.No | Phương pháp & Mô tả | Thí dụ |
---|---|---|
1 | get_value(value, *processors, **kwargs) Bởi một bộ xử lý nhất định và các đối số từ khóa, giá trị được xử lý bằng phương thức get_value (). |
|
2 | add_value(field_name, value, *processors, **kwargs) Nó xử lý giá trị và thêm vào trường nơi nó được chuyển đầu tiên qua get_value bằng cách đưa ra các bộ xử lý và đối số từ khóa trước khi chuyển qua bộ xử lý đầu vào trường. |
|
3 | replace_value(field_name, value, *processors, **kwargs) Nó thay thế dữ liệu đã thu thập bằng một giá trị mới. |
|
4 | get_xpath(xpath, *processors, **kwargs) Nó được sử dụng để trích xuất các chuỗi unicode bằng cách đưa ra các bộ xử lý và các đối số từ khóa bằng cách nhận XPath . |
|
5 | add_xpath(field_name, xpath, *processors, **kwargs) Nó nhận XPath đến trường trích xuất các chuỗi unicode. |
|
6 | replace_xpath(field_name, xpath, *processors, **kwargs) Nó thay thế dữ liệu được thu thập bằng XPath từ các trang web. |
|
7 | get_css(css, *processors, **kwargs) Nó nhận bộ chọn CSS được sử dụng để trích xuất các chuỗi unicode. |
|
số 8 | add_css(field_name, css, *processors, **kwargs) Nó tương tự như phương thức add_value () với một điểm khác biệt là nó thêm bộ chọn CSS vào trường. |
|
9 | replace_css(field_name, css, *processors, **kwargs) Nó thay thế dữ liệu được trích xuất bằng cách sử dụng CSS selector. |
|
10 | load_item() Khi dữ liệu được thu thập, phương pháp này sẽ điền vào mục với dữ liệu đã thu thập và trả về. |
|
11 | nested_xpath(xpath) Nó được sử dụng để tạo bộ tải lồng nhau với bộ chọn XPath. |
|
12 | nested_css(css) Nó được sử dụng để tạo bộ tải lồng nhau với bộ chọn CSS. |
|
Bảng sau hiển thị các thuộc tính của các đối tượng ItemLoader:
Sr.No | Thuộc tính & Mô tả |
---|---|
1 | item Nó là một đối tượng mà Trình tải mục thực hiện phân tích cú pháp. |
2 | context Đó là ngữ cảnh hiện tại của Trình tải mục đang hoạt động. |
3 | default_item_class Nó được sử dụng để đại diện cho các mục, nếu không được đưa ra trong hàm tạo. |
4 | default_input_processor Các trường không chỉ định bộ xử lý đầu vào là những trường duy nhất mà bộ xử lý default_input_processor được sử dụng. |
5 | default_output_processor Các trường không chỉ định bộ xử lý đầu ra là những trường duy nhất mà bộ xử lý default_output_processor được sử dụng. |
6 | default_selector_class Nó là một lớp được sử dụng để xây dựng bộ chọn, nếu nó không được đưa ra trong hàm tạo. |
7 | selector Nó là một đối tượng có thể được sử dụng để trích xuất dữ liệu từ các trang web. |
Máy xúc lật lồng nhau
Nó được sử dụng để tạo bộ tải lồng nhau trong khi phân tích cú pháp các giá trị từ phần phụ của tài liệu. Nếu bạn không tạo bộ tải lồng nhau, bạn cần chỉ định XPath hoặc CSS đầy đủ cho mỗi giá trị mà bạn muốn trích xuất.
Ví dụ: giả sử rằng dữ liệu đang được trích xuất từ trang tiêu đề -
<header>
<a class = "social" href = "http://facebook.com/whatever">facebook</a>
<a class = "social" href = "http://twitter.com/whatever">twitter</a>
<a class = "email" href = "mailto:[email protected]">send mail</a>
</header>
Tiếp theo, bạn có thể tạo bộ tải lồng nhau với bộ chọn tiêu đề bằng cách thêm các giá trị liên quan vào tiêu đề -
loader = ItemLoader(item = Item())
header_loader = loader.nested_xpath('//header')
header_loader.add_xpath('social', 'a[@class = "social"]/@href')
header_loader.add_xpath('email', 'a[@class = "email"]/@href')
loader.load_item()
Tái sử dụng và mở rộng Máy xúc vật phẩm
Máy xúc vật phẩm được thiết kế để giảm bớt việc bảo trì vốn trở thành một vấn đề cơ bản khi dự án của bạn có thêm nhện.
Ví dụ: giả sử rằng một trang web có tên sản phẩm của họ được đặt trong ba dấu gạch ngang (ví dụ --DVD ---). Bạn có thể loại bỏ những dấu gạch ngang đó bằng cách sử dụng lại Trình tải mục sản phẩm mặc định, nếu bạn không muốn nó trong tên sản phẩm cuối cùng như được hiển thị trong mã sau:
from scrapy.loader.processors import MapCompose
from demoproject.ItemLoaders import DemoLoader
def strip_dashes(x):
return x.strip('-')
class SiteSpecificLoader(DemoLoader):
title_in = MapCompose(strip_dashes, DemoLoader.title_in)
Bộ xử lý tích hợp sẵn có
Sau đây là một số bộ vi xử lý tích hợp thường được sử dụng:
lớp scrapy.loader.processors.Identity
Nó trả về giá trị ban đầu mà không thay đổi nó. Ví dụ -
>>> from scrapy.loader.processors import Identity
>>> proc = Identity()
>>> proc(['a', 'b', 'c'])
['a', 'b', 'c']
lớp scrapy.loader.processors.TakeFirst
Nó trả về giá trị đầu tiên không null / không rỗng từ danh sách các giá trị đã nhận. Ví dụ -
>>> from scrapy.loader.processors import TakeFirst
>>> proc = TakeFirst()
>>> proc(['', 'a', 'b', 'c'])
'a'
lớp scrapy.loader.processors.Join (dấu tách = u '')
Nó trả về giá trị được gắn vào dấu phân cách. Dấu phân tách mặc định là u '' và nó tương đương với hàmu' '.join. Ví dụ -
>>> from scrapy.loader.processors import Join
>>> proc = Join()
>>> proc(['a', 'b', 'c'])
u'a b c'
>>> proc = Join('<br>')
>>> proc(['a', 'b', 'c'])
u'a<br>b<br>c'
class scrapy.loader.processors.Compose (* các hàm, ** default_loader_context)
Nó được xác định bởi một bộ xử lý trong đó mỗi giá trị đầu vào của nó được chuyển cho hàm đầu tiên và kết quả của hàm đó được chuyển cho hàm thứ hai, v.v., cho đến khi hàm ast trả về giá trị cuối cùng là đầu ra.
Ví dụ -
>>> from scrapy.loader.processors import Compose
>>> proc = Compose(lambda v: v[0], str.upper)
>>> proc(['python', 'scrapy'])
'PYTHON'
class scrapy.loader.processors.MapCompose (* các hàm, ** default_loader_context)
Nó là một bộ xử lý trong đó giá trị đầu vào được lặp lại và hàm đầu tiên được áp dụng cho mỗi phần tử. Tiếp theo, kết quả của các lệnh gọi hàm này được nối với nhau để xây dựng có thể lặp lại mới sau đó được áp dụng cho hàm thứ hai, v.v., cho đến hàm cuối cùng.
Ví dụ -
>>> def filter_scrapy(x):
return None if x == 'scrapy' else x
>>> from scrapy.loader.processors import MapCompose
>>> proc = MapCompose(filter_scrapy, unicode.upper)
>>> proc([u'hi', u'everyone', u'im', u'pythonscrapy'])
[u'HI, u'IM', u'PYTHONSCRAPY']
class scrapy.loader.processors.SelectJmes (json_path)
Lớp này truy vấn giá trị bằng cách sử dụng đường dẫn json được cung cấp và trả về kết quả đầu ra.
Ví dụ -
>>> from scrapy.loader.processors import SelectJmes, Compose, MapCompose
>>> proc = SelectJmes("hello")
>>> proc({'hello': 'scrapy'})
'scrapy'
>>> proc({'hello': {'scrapy': 'world'}})
{'scrapy': 'world'}
Sau đây là đoạn mã, truy vấn giá trị bằng cách nhập json -
>>> import json
>>> proc_single_json_str = Compose(json.loads, SelectJmes("hello"))
>>> proc_single_json_str('{"hello": "scrapy"}')
u'scrapy'
>>> proc_json_list = Compose(json.loads, MapCompose(SelectJmes('hello')))
>>> proc_json_list('[{"hello":"scrapy"}, {"world":"env"}]')
[u'scrapy']