Python3 Scrapy爬虫框架-通用爬虫介绍

  • CrawlSpider:Scrapy提供的一个通用Spider
    • 官方文档链接:http://scrapy.readthedocs.io/en/latest/topics/spiders.html#crawlspider
    • 在Spider里,使用数据结构Rule表示用来实现页面的提取的爬取规则;Rule里包含提取和跟进页面的配置,Spider会根据Rule来确定当前页面中的哪些链接需要继续爬取、哪些页面的爬取结果需要用哪个方法解析等
    • CrawlSpider继承自Spider类,它还提供了一个非常重要的属性和方法。
      • rules:爬取规则属性,是包含一个或多个Rule对象的列表,每个Rule对爬取网站的动作都做了定义,CrawlSpider会读取rules的每一个Rule并进行解析
      • parse_start_url():一个可重写的方法;当start_urls里对应的Request得到Response时,该方法被调用,它会分析Response并必须返回Item对象或者Request对象
    • Rule的定义
1 class scrapy.contrib.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)
2 
3 # link_extractor:是Link Extractor对象,Spider通过它可以知道从爬取的页面中提取哪些链接,提取出的链接会自动生成Request,它又是一个数据结构,一般常用LxmlLinkExtractor对象作为参数
4 # callback:即回调函数,每次从link_extractor中获取到链接时,该函数将会调用。该回调函数接收一个response作为其第一个参数,并返回一个包含Item或Request对象的列表
5 # 注意:避免使用parse()作为回调函数。由于CrawlSpider使用parse()方法来实现其逻辑,如果parse()方法覆盖了,CrawlSpider将会运行失败
6 # cb_kwargs:字典,它包含传递给回调函数的参数
7 # follow:布尔值,即True或False,它指定根据该规则从response提取的链接是否需要跟进;如果callback参数为None,follow默认设置为True,否则默认为False
8 # process_links:指定处理函数,从link_extractor中获取到链接列表时,该函数将会调用,它主要用于过滤
9 # process_request:同样是指定处理函数,根据该Rule提取到每个Request时,该函数都会调用,对Request进行处理;该函数必须返回Request或者None
    • LxmlLinkExtractor对象
 1 # LxmlLinkExtractor对象
 2 scrapy.linkextractors.lxmlhtml.LxmlLinkExtractor(allow=(), deny=(), allow_domains=(), deny_domains=(), deny_extensions=None, restrict_xpaths=(), restrict_css=(), tags=('a', 'area'), attrs=('href', ), canonicalize=False, unique=True, process_value=None, strip=True)
 3 
 4 # allow是一个正则表达式或正则表达式列表,它定义了从当前页面提取出的链接哪些是符合要求的,只有符合要求的链接才会被跟进
 5 # deny则与allow相反
 6 # allow_domains定义了符合要求的域名,只有此域名的链接才会被跟进生成新的Request,它相当于域名白名单
 7 # deny_domains则相反,相当于域名黑名单
 8 # restrict_xpaths定义了从当前页面中XPath匹配的区域提取链接,其值是XPath表达式或XPath表达式列表
 9 # restrict_css定义了从当前页面中CSS选择器匹配的区域提取链接,其值是CSS选择器或CSS选择器列表
10 # 文档的参数说明:http://scrapy.readthedocs.io/en/latest/topics/link-extractors.html#module-scrapy.linkextractors.lxmlhtml
  • Item Loader:提供的一系列API可以分析原始数据对Item进行赋值;Item提供的是保存抓取数据的容器,而Item Loader提供的是填充容器的机制
 1 class scrapy.loader.ItemLoader([item, selector, response, ] **kwargs)
 2 
 3 # 返回一个新的Item Loader来填充给定的Item。
 4 # 如果没有给出Item,则使用中的类自动实例化default_item_class,传入selector和response参数来使用选择器或响应参数实例化
 5 # item:它是Item对象,可以调用add_xpath()、add_css()或add_value()等方法来填充Item对象
 6 # selector:它是Selector对象,用来提取填充数据的选择器
 7 # response:它是Response对象,用于使用构造选择器的Response
 8 # 一个比较典型的Item Loader实例
 9 from scrapy.loader import ItemLoader
10 from project.items import Product
11 
12 def parse(self, response):
13     loader = ItemLoader(item=Product(), response=response) # 用该Item和Response对象实例化ItemLoader
14     # 用add_xpath()、add_css()、add_value()等方法对不同属性依次赋值,最后调用load_item()方法实现Item的解析
15     # 调用add_xpath()方法把来自两个不同位置的数据提取出来,分配给name属性
16     loader.add_xpath('name', '//div[@class="product_name"]')
17     loader.add_xpath('name', '//div[@class="product_title"]')
18     loader.add_xpath('price', '//p[@id="price"]')
19     loader.add_css('stock', 'p#stock]')
20     # Item Loader每个字段中都包含了一个Input Processor(输入处理器)和一个Output Processor(输出处理器)
21     # Input Processor收到数据时立刻提取数据,Input Processor的结果被收集起来并且保存在ItemLoader内,但是不分配给Item
22     # 收集到所有的数据后,load_item()方法被调用来填充再生成Item对象
23     # 在调用时会先调用Output Processor来处理之前收集到的数据,然后再存入Item中,这样就生成了Item
24     loader.add_value('last_updated', 'today')
25     return loader.load_item()
  • 内置的的Processor
    • Identity:是最简单的Processor,不进行任何处理,直接返回原来的数据
    • TakeFirst:TakeFirst返回列表的第一个非空值,类似extract_first()的功能,常用作Output Processor
1 from scrapy.loader.processors import TakeFirst
2 
3 processor = TakeFirst()
4 # 经过此Processor处理后的结果返回了第一个不为空的值
5 print(processor(['', 1, 2, 3])) # 1
    • Join:相当于字符串的join()方法,可以把列表拼合成字符串,字符串默认使用空格分隔
1 from scrapy.loader.processors import Join
2 
3 processor = Join()
4 print(processor(['one', 'two', 'three'])) # one two three
5 processor = Join(',')
6 print(processor(['one', 'two', 'three'])) # one,two,three
    • Compose:是用给定的多个函数的组合而构造的Processor,每个输入值被传递到第一个函数,其输出再传递到第二个函数,依次类推,直到最后一个函数返回整个处理器的输出
1 from scrapy.loader.processors import Compose
2 
3 processor = Compose(str.upper, lambda s: s.strip())
4 print(processor(' hello world')) # HELLO WORLD
    • MapCompose:与Compose类似,MapCompose可以迭代处理一个列表输入值
1 from scrapy.loader.processors import MapCompose
2 
3 processor = MapCompose(str.upper, lambda s: s.strip())
4 print(processor(['Hello', 'World', 'Python'])) # ['HELLO', 'WORLD', 'PYTHON']
    • SelectJmes:可以查询JSON,传入Key,返回查询所得的Value;需要先安装Jmespath库才可以使用它
1 pip install jmespath
1 from scrapy.loader.processors import SelectJmes
2 
3 proc = SelectJmes('foo')
4 processor = SelectJmes('foo')
5 print(processor({'foo': 'bar'})) # bar

 

 
posted @ 2020-08-30 15:40  陨落的星尘  阅读(344)  评论(0编辑  收藏  举报