Python Scrapy框架有一个概念,叫做Item Loaders。一旦[Scrapy项目]被定义,这些项目加载器就被用来将数据加载到[Scrapy项目]中。在这个过程中,我们可以应用输入处理器和输出处理器,以各种方式清理提取的数据。通过一个ItemLoader类和一些小而有用的函数,你可以剥离不需要的字符,清理空白字符,或者以你认为合适的方式修改正在收集的数据。现在我们来看看一个Scrapy Item Loader的例子。
添加输入/输出处理器
要使用Item Loader,你首先要导航到你的Scrapy项目中的items.py文件。在 items.py 文件中,你可以导入要使用的项目装载器处理器。这就是项目加载器如何在数据通过scrapy过程时对其进行修改。这里是我们更新的items.py文件。
import scrapy
from itemloaders.processors import TakeFirst, MapCompose
from w3lib.html import remove_tags
def remove_whitespace(value):
return value.strip()
def to_dollars(value):
return value.replace('£', '$')
class BookstoscrapeItem(scrapy.Item):
booktitle = scrapy.Field(
input_processor=MapCompose(remove_tags),
output_processor=TakeFirst()
)
bookrating = scrapy.Field(
input_processor=MapCompose(remove_tags),
output_processor=TakeFirst()
)
bookprice = scrapy.Field(
input_processor=MapCompose(remove_tags, to_dollars),
output_processor=TakeFirst()
)
bookavailability = scrapy.Field(
input_processor=MapCompose(remove_tags, remove_whitespace),
output_processor=TakeFirst()
)
Spider中的项目加载器
为了让搜刮的数据通过我们刚刚设置的输入和输出处理器进行实际处理,ItemLoader需要被导入到主Spider中。一旦进入Spider,我们就会使用一种特殊的语法来通过管道加载数据。重要的变化在这里突出显示在books.py中。
import scrapy
from bookstoscrape.items import BookstoscrapeItem
from scrapy.loader import ItemLoader
class BooksSpider(scrapy.Spider):
name = 'books'
allowed_domains = ['books.toscrape.com']
start_urls = ['http://books.toscrape.com/']
def parse(self, response):
for book in response.xpath('//article'):
l = ItemLoader(item=BookstoscrapeItem(), selector=book)
l.add_xpath('booktitle', './/a/text()')
l.add_xpath('bookrating', './/p/@class')
l.add_xpath('bookprice', './/div[2]/p/text()')
l.add_xpath('bookavailability', './/div[2]/p[2]/i/following-sibling::text()')
yield l.load_item()
next_page = response.css('.next a').attrib['href']
if next_page is not None:
yield response.follow(next_page, callback=self.parse)
运行Spider
当Spider运行时,数据被处理成我们想要的样子。任何HTML标签都被删除了,空格和换行符也被删除了,货币也被改成了美元。
[
{
"booktitle": "A Light in the ...",
"bookrating": "star-rating Three",
"bookprice": "$51.77",
"bookavailability": "In stock"
},
{
"booktitle": "Tipping the Velvet",
"bookrating": "star-rating One",
"bookprice": "$53.74",
"bookavailability": "In stock"
},
{
"booktitle": "Soumission",
"bookrating": "star-rating One",
"bookprice": "$50.10",
"bookavailability": "In stock"
},
{
"booktitle": "Sharp Objects",
"bookrating": "star-rating Four",
"bookprice": "$47.82",
"bookavailability": "In stock"
}
]
如何使用Scrapy项目加载器摘要
Item Loader方法的语法使主Spider中的parse()方法在视觉上更吸引人,更干净。这给了Spider一个明确的意图,即我们要做什么,这使得代码更容易维护和自我文档化。ItemLoaders提供了许多有趣的方法来组合数据,格式化它们,并清理它们。ItemLoaders通过不同的处理器类传递来自XPath/CSS表达式的值。处理器是快速而简单的函数。有很多可供选择的,但我们在这里看了MapCompose和TakeFirst。我们还看到了如何向类中添加我们自己的自定义方法,以我们认为合适的方式清理数据。要带走的关键概念是,处理器只是简单和小的函数,对我们的XPath/CSS结果进行后处理。
