CrawlSpider 和 Item Loader
文章目录
目的:实现一个通用爬虫,在新增一个爬虫时,只需要实现这些网站的爬取规则和提取规则就可以。
1、新建项目
目标网址:链接
抓取内容:标题、正文、时间、其他、
新建一个Scrapy
项目,名字为scrapyuniversal。
scrapy startproject douban_movie
创建一个CrawlSpider
模版。
(.venv) ➜ douban git:(master) ✗ scrapy genspider -l # 查看模版
Available templates:
basic
crawl
csvfeed
xmlfeed
(.venv) ➜ douban git:(master) ✗ scrapy genspider -t crawl douban movie.douban.com
douban.py文件内容如下:
# -*- coding: utf-8 -*-
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from douban_movie.items import DoubanLoader, DoubanMovieItem
class DoubanSpider(CrawlSpider):
name = 'douban'
allowed_domains = ['movie.douban.com']
start_urls = ['https://movie.douban.com/top250?start=0&filter=']
rules = (
Rule(LinkExtractor(restrict_xpaths="//div[@class='hd']"), callback='parse_item'),
Rule(LinkExtractor(restrict_xpaths="//span[@class='next']/a"))
)
def parse_item(self, response):
loader = DoubanLoader(item=DoubanMovieItem(), response=response)
loader.add_xpath('name', '//*[@id="content"]/h1/span[1]/text()')
loader.add_value('url', response.url)
loader.add_xpath('text', '//*[@id="link-report"]/span[1]/span/text()')
yield loader.load_item()
我们主要编写rules
属性,注意这里的默认回调函数不是parse
而是parse_item
。
2、定义Rule
起始URL:https://movie.douban.com/top250?start=0&filter=
之后Spider爬取start_urls列表下的每个链接,在得到Response
后,Spider
就会根据每个Rule
来提取这个页面内的超链接,去生成进一步的Request。
Rule参数
Rule(link_extractor, callback=None, cb_kwargs=None, follow=None,process_links=None, process_request=None)
- link_extractor:是
Link Extractor
的对象,通过它Spider
可以知道从页面提取那些链接,提取的链接会自动生成Request,它本身是一个数据结构,通常用LxmlLinkExtractor
对象作为参数。 - **callback:**回调函数,每次从link_extractor中获取到链接后,该函数会调用。该回调函数接受一个response作为第一个参数,并返回一个包含
Item
或Request
对象的列表。**注意:**避免使用parse()作为回调函数,在CrawlSpider中使用parse()方法实现逻辑。 - **cb_kwargs:**字典,包含传递给回调函数的参数。
- **follow:**布尔值,指定根据该规则从
Response
提取的链接是否需要跟进,默认为True
。 - **process_links:**指定处理函数,从link_extract中获取到链表列表时,改函数会调用,主要用来过滤。
- **process_request:**指定处理函数,根据
Rule
提取到每个Request
时,改函数会调用,对Request
进行处理。改函数必须返回Request
或者None
。
LinkExtractor:
class LxmlLinkExtractor(FilteringLinkExtractor):
def __init__(self, allow=(), deny=(), allow_domains=(), deny_domains=(), restrict_xpaths=(),
tags=('a', 'area'), attrs=('href',), canonicalize=False,
unique=True, process_value=None, deny_extensions=None, restrict_css=(),
strip=True):
- allow:要抓取url规则,接受正则表达式,接受可迭代对象。
- deny:不抓取的规则,参数和allow一样。
- allow_domains:抓取哪个域名下的网站,前面写了后面就不用了。
- deny_domains:和
allow_domains
相反。 - restrict_xpaths:在网页哪个区域里提取链接,规定提取链接的位置。
- tags:默认提取a标签和area标签
- attrs:默认提取tags里的href属性,也就是url链接
- canonicalize:url规范化
- unique:url是否要唯一,默认true
- process_value:接受一个函数,对提取的地址进行加工
- deny_extensions:排除非网页链接,默认None
- strip:把地址多余空格删除
默认排除非网页链接
IGNORED_EXTENSIONS = [
# images
'mng', 'pct', 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'pst', 'psp', 'tif',
'tiff', 'ai', 'drw', 'dxf', 'eps', 'ps', 'svg',
# audio
'mp3', 'wma', 'ogg', 'wav', 'ra', 'aac', 'mid', 'au', 'aiff',
# video
'3gp', 'asf', 'asx', 'avi', 'mov', 'mp4', 'mpg', 'qt', 'rm', 'swf', 'wmv',
'm4a', 'm4v',
# office suites
'xls', 'xlsx', 'ppt', 'pptx', 'pps', 'doc', 'docx', 'odt', 'ods', 'odg',
'odp',
# other
'css', 'pdf', 'exe', 'bin', 'rss', 'zip', 'rar',
]
3、Item Loader
Item Loader每个字段都包含一个Input Processor
输入处理器和一个Output Process
输出处理器。
Input Processor收到数据后立刻提取数据,结果被收集起来并且保存到Item Loader
中,但是分配给Item
。收集数据完成后,Load_item()
方法被调用来填充再生成Item
对象。在调用时会先调用Output Processor
来处理之前收集到的数据,然后再存入Item
中。
内置Processor
Identity
不进行任何处理,直接返回原来的数据
TakeFirst
返回列表的第一个非空值,常用作Output Processor
。
Join
相当于字符串Join()方法,可以把列表拼接成字符串,字符串默认空格分隔。可以更改默认分隔符。
Compose
用给定的多个函数组合构造的Processor
,每个输入值被传递到第一个函数,其输出再穿入到第二个函数,直到最后一个函数。
MapCompose
与Compose类似,但是它可以处理一个列表的输入值。
SelectJmes
可以查询JSON,传入Key,返回查询所得到的Value。不过要先安装Jmespath
库才可以使用。