python scrapy爬虫项目加载器详解
2022年5月30日大约 2 分钟约 534 字
直接将Item
和CSS
选择器绑定到一起,直接把选择出来的数据放入Item中。
item loader的一般使用
>>> vim ArticleSpider/spiders/jobbole.py
class JobboleSpider(scrapy.Spider):
name = 'jobbole'
allowed_domains = ['blog.jobbole.com']
start_urls = ['http://blog.jobbole.com/all-posts/']
...
# 文章详情页的内容解析
def article_parse(self, response):
# 通过item loader加载item
item_loader = ItemLoader(item=ArticleItem(), response=response)
item_loader.add_css("title", ".grid-8 .entry-header > h1::text")
item_loader.add_css("content", ".grid-8 .entry")
item_loader.add_css("add_time", ".grid-8 .entry-meta p::text")
item_loader.add_value("url", response.url)
item_loader.add_value("url_object_id", get_md5(response.url))
item_loader.add_value("head_img_url", [head_img_url])
item_loader.add_css("star", "h10::text")
article_item = item_loader.load_item()
yield article_item # 传递到pipeline。请看settings.py中ITEM_PIPELINES字典
使用
Item Loader
的两个问题:
- 原始数据需要处理
- 解决办法:在Item内使用字段的处理器
- 不管数据有几个,获取的是一个数组
- 解决办法:在Item内字段处理器中使用
TakeFirst()
方法
配合item 的processor处理器的使用
>>> vim ArticleSpider/items.py
# MapCompose:可以调用多个函数依次运行
# TakeFirst: 与extract_first()函数一样,只选择数组第一个数据
# Join: 把数组用符号连接成字符串,比如Join(",")
from scrapy.loader.processors import MapCompose, TakeFirst, Join
# add_time键处理函数
def date_convert1(value):
add_time_match = re.match("[\s\S]*?(\d{2,4}[/-]\d{1,2}[/-]\d{1,2})[\s\S]*", value)
if add_time_match:
add_time = add_time_match.group(1)
else:
add_time = value.strip()
return add_time
def date_convert2(value):
try:
add_time = datetime.datetime.strptime(value, "%Y/%m/%d").date()
except Exception as e:
add_time = datetime.datetime.now().date()
return add_time
class ArticleItem(scrapy.Item):
...
add_time = scrapy.Field(
input_processor=MapCompose(date_convert1, date_convert2), # 处理原始数据
output_processor=TakeFirst() # 只取数组中第一个数据
) # 文章添加时间
...
自定义item loader
可以设置默认的
default_output_processor = TakeFirst()
>>> vim ArticleSpider/items.py
from scrapy.loader import ItemLoader
class ArticleItemLoader(ItemLoader):
# 自定义item loader
default_output_processor = TakeFirst()
# 默认item处理器,什么都不做
def default_processor(value):
return value
class ArticleItem(scrapy.Item):
...
head_img_url = scrapy.Field(
# 图像URL需要一个数组类型,不取第一个数据,定义一个默认处理器覆盖掉
# 另外注意在使用sql保存时,需要取出数组第一个
output_processor=default_processor
) # 封面图URL
...
##########################################################################################
>>> vim ArticleSpider/spiders/jobbole.py
from ArticleSpider.items import ArticleItemLoader
class JobboleSpider(scrapy.Spider):
name = 'jobbole'
allowed_domains = ['blog.jobbole.com']
start_urls = ['http://blog.jobbole.com/all-posts/']
...
# 文章详情页的内容解析
def article_parse(self, response):
...
# 通过item loader加载item
item_loader = ArticleItemLoader(item=ArticleItem(), response=response)
...