python爬虫scrapy框架教程_爬虫(十八):Scrapy框架(五) Scrapy通用爬虫|python基础教程|python入门|python教程...

https://www.xin3721.com/eschool/pythonxin3721/

1. Scrapy通用爬虫

通过Scrapy,我们可以轻松地完成一个站点爬虫的编写。但如果抓取的站点量非常大,比如爬取各大媒体的新闻信息,多个Spider则可能包含很多重复代码。

如果我们将各个站点的Spider的公共部分保留下来,不同的部分提取出来作为单独的配置,如爬取规则、页面解析方式等抽离出来做成一个配置文件,那么我们在新增一个爬虫的时候,只需要实现这些网站的爬取规则和提取规则即可。

这一章我们就来了解下Scrapy通用爬虫的实现方法。

1.1 CrawlSpider

在实现通用爬虫之前,我们需要先了解一下CrawlSpider,官方文档:https://scrapy.readthedocs.io/en/latest/topics/spiders.html#crawlspider。

CrawlSpider是Scrapy提供的一个通用Spider。在Spider里,我们可以指定一些爬取规则来实现页面的提取,这些爬取规则由一个专门的数据结构Rule表示。Rule里包含提取和跟进页面的配置,Spider会根据Rule来确定当前页面中的哪些链接需要继续爬取、哪些页面的爬取结果需要用哪个方法解析等。

CrawlSpider继承自Spider类。除了Spider类的所有方法和属性,它还提供了一个非常重要的属性和方法。

rules,它是爬取规则属性,是包含一个或多个Rule对象的列表。每个Rule对爬取网站的动作都做了定义,CrawlSpider会读取rules的每一个Rule并进行解析。

parse_start_url(),它是一个可重写的方法。当start_urls里对应的Request得到Response时,该方法被调用,它会分析Response并必须返回Item对象或者Request对象。

这里最重要的内容莫过于Rule的定义了:

2245494952-0.png

Rule参数:

link_extractor:是Link Extractor对象。通过它,Spider可以知道从爬取的页面中提取哪些链接。提取出的链接会自动生成Request。它又是一个数据结构,一般常用LxmlLinkExtractor对象作为参数。

2245491222-1.png

allow是一个正则表达式或正则表达式列表,它定义了从当前页面提取出的链接哪些是符合要求的,只有符合要求的链接才会被跟进。deny则相反。allow_domains定义了符合要求的域名,只有此域名的链接才会被跟进生成新的Request,它相当于域名向名单。deny_domains则相反,相当于域名黑名单。restrict_xpaths定义了从当前页面中XPath匹配的区域提取链接,其值是XPath表达式或XPath表达式列表。restrict_css定义了从当前页面中css选择器匹配的区域提取链接,其值是css选择器或css选择器列表还有一些其他参数代表了提取链接的标签、是否去重、链接的处理等内容,使用的频率不高。

参考文档:https://scrapy.readthedocs.io/en/latest/topics/link-extractors.html#module-scrapy.linkextractors.lxmlhtml。

callback:即回调函数,和之前定义Request的callback有相同的意义。每次从link_extractor中获取到链接时,该函数将会调用。该回调函数接收一个response作为其第一个参数,并返回一个包含Item或Request对象的列表。注意,避免使用pars()作为回调函数。由于CrawlSpider使用parse()方法来实现其逻辑,如果parse()方法覆盖了,CrawlSpider将会运行失败。

cb_kwargs:字典,它包含传递给回调函数的参数。

follow:布尔值,即True或False,它指定根据该规则从response提取的链接是否需要跟进。如果 callback参数为None,follow默认设置为True,否则默认为False。

process_links:指定处理函数,从link_extractor中获取到链接列表时,该函数将会调用, 它主要用于过滤。

process_request:同样是指定处理函数,根据该Rule提取到每个Request时,该函数部会调用,对Request进行处理。该函数必须返回Request或者None。

以上内容便是CraefISpider中的核心Rule的基本用法。但这些内容可能还不足以完成一个CrawlSpider爬虫。下面我们利用CrawlSpider实现新闻网站的爬取实例,来更好地理解Rule的用法。

1.2 Item Loader

我们了解了利用CrawlSpider的Rule来定义页面的爬取逻辑,这是可配置化的一部分内容。但是,Rule并没有对Item的提取方式做规则定义。对于Item的提取,我们需要借助另一个模块Item Loader来实现。

Item Loader提供一种便捷的机制来帮助我们方便地提取Item。它提供的一系列API可以分析原始数据对Item进行赋值。Item提供的是保存抓取数据的容器,而Item Loader提供的是填充容器的机制。有了它,数据的提取会变得更加规则化。

Item LoaderAPI参数:

item:它是Item对象,可以调用add_xpath()、add_css()或add_value()等方法来填充Item对象。

selector:它是Selector对象,用来提取填充数据的选择器。

response:它是Response对象,用于使用构造选择器的Response。

实例:

fromscrapy.loaderimportItemLoader

fromscrapyDemo.itemsimportProduct

defparse(self,response): loader=ItemLoader(item=Product(),response=response) loader.add_xpath('name','//div[@class="product_name"]') loader.add_xpath('name','//div[@class="product_title"]') loader.add_xpath('price','//p[@id="price"]') loader.add_css('stock','p#stock]') loader.add_value('last_updated','today') returnloader.load_item()

这里首先声明一个Product Item,用该Item和Response对象实例化Item Loader,调用add_xpath()方法把来向两个不同位置的数据提取出来,分配给name属性,再用add_xpath()、add_css()、add_value()等方法对不同属性依次赋值,最后调用load_item()方法实现Item的解析。这种方式比较规则化,我们可以把一些参数和规则单独提取出来做成配置文件或存到数据库,即可实现可配置化。

另外,Item Loader每个字段中都包含了一个Input Processor(输入处理器)和一个Output Processor(输出处理器)。Input Processor收到数据时立刻提取数据,Input Processor的结果被收集起来并且保存在ltemLoader内,但是不分配给Item。收集到所有的数据后,load_item()方法被调用来填充再生成Item对象 。在调用时会先调用Output Processor来处理之前收集到的数据,然后再存入Item中,这样就生成了Item。

内置的Processor:

(1) Identity

Identity是最简单的Processor,不进行任何处理,直接返回原来的数据。

(2) TakeFirst

TakeFirst返回列表的第一个非空值,类似extract_first()的功能,常用作Output Processor。

fromscrapy.loader.processorsimportTakeFirst

processor=TakeFirst()

print(processor(['',1,2,3]))

运行结果为1。

(3) Join

Join方法相当于字符串的join()方法,可以把列表并结成字符串,字符串默认使用空格分隔。

fromscrapy.loader.processorsimportJoin

processor=Join()

print(processor(['one','two','three']))

运行结果为one two three。

它也可以通过参数更改默认的分隔符,例如改成逗号:

fromscrapy.loader.processorsimportJoin

processor=Join(',')

print(processor(['one','two','three']))

运行结果为one,two,three。

(4) Compose

Compose是用给定的多个函数的组合而构造的Processor,每个输入值被传递到第一个函数,其输出再传递到第二个函数,依次类推,直到最后一个函数返回整个处理器的输出。

fromscrapy.loader.processorsimportCompose

processor=Compose(str.upper,lambdas:s.strip())

print(processor('hello world'))

运行结果为HELLO WORLD。

在这里我们构造了一个Compose Processor,传入一个开头带有空格的字符串。Compose Processor的参数有两个:第一个是str.upper,它可以将字母全部转为大写;第二个是一个匿名函数,它调用strip()方法去除头尾空白字符。Compose会顺次调用两个参数,最后返回结果的字符串全部转化为大写并且去除了开头的空格。

(5) MapCompose

与Compose类似,MapCompose可以迭代处理一个列表输入值。

fromscrapy.loader.processorsimportMapCompose

processor=MapCompose(str.upper,lambdas:s.strip())

print(processor(['Hello','World','Python']))

运行结果为['HELLO','WORLD','PYTHON']。

被处理的内容是一个可迭代对象,MapCompose会将该对象遍历然后依次处理。

(6) SelectJmes

SelectJmes可以查询JSON,传入Key,返回查询所得的Value。不过需要先安装jmespath库才可以使用它。

pip install jmespath

安装好jmespath之后,便可以使用这个Processor了。

fromscrapy.loader.processorsimportSelectJmes

processor=SelectJmes('foo')

print(processor({'foo':'bar'}))

运行结果为:bar。

以上内容便是一些常用的Processor,在本节的实例中我们会使用Processor来进行数据的处理。接下来,我们用一个实例来了解Item Loader的用法。

1.3 通用爬虫案例

起点作为主流的小说网站,在防止数据采集反面还是做了准备的,其对主要的数字采用了自定义的编码映射取值,想直接通过页面来实现数据的获取,是无法实现的。

单独获取数字还是可以实现的,通过requests发送请求,用正则去匹配字符元素,并再次匹配其映射关系的url,获取到的数据通过font包工具解析成字典格式,再做编码匹配,起点返回的编码匹配英文数字,英文数字匹配阿拉伯数字,最后拼接,得到实际的数字字符串,但这样多次发送请求,爬取效率会大大降低。本次集中爬取舍弃了爬取数字,选择了较容易获取的评分数字。评分值默认为0 ,是从后台推送的js数据里取值更新的。

但是这太复杂了,我没空搞,现在写博客都是挤出时间来写。

1.3.1 新建项目

先新建Scrapy项目,名为qd。

scrapy startproject qd

创建一个CrawlSpider,需要先制定一个模板。我们可以先看看有哪些可用模版。

scrapy genspider -l

运行结果:

2245492G5-2.png

之前创建Spider的时候,我们默认使用了第一个模板basic。这次要创建CrawlSpider,就需要使用第二个模板crawl。

scrapy genspider -t crawl read qidian.com

运行之后便会生成一个CrawlSpider。

这次生成的Spider内容多了一个rules属性的定义。Rule第一个参数是LinkExtractor,就是上文所说的LxmllinkExtractor,只是名称不同。同时,默认的回调函数也不再是parse,而是parse_item。

1.3.2 定义Rule

要实现小说信息的爬取,我们需要做的就是定义好Rule,然后实现解析函数。下面我们就来一步步实现这个过程。

首先将start_urls修改为起始链接。

start_urls=['https://www.qidian.com/all?orderId=&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=0&page=1']

之后,Spider爬取start_urls里面的每一个链接。所以这里第一个爬取的页面就是我们刚才所定义的链接。得到Response之后,Spider就会根据每一个Rule来提取这个页面内的超链接,去生成进一步的Request。接下来,我们就需要定义Rule来指定提取哪些链接。

224549DZ-3.png

这是起点小说网的列表页,下一步自然就是将列表中的每一条小说详情的链接提取出来。这里直接指定这些链接所在区域即可。

rules:

rules=(

#匹配全部主页面的url规则 深度爬取子页面

Rule(LinkExtractor(allow=(r'

Scrapy是一个基于Python爬虫框架,它可以帮助我们快速高效地抓取网站数据。在这里,我将介绍Scrapy的基本用法,让您能够快速入门。 安装Scrapy ----------------------- 在安装Scrapy之前,我们需要先安装Python。然后,我们可以通过以下命令来安装Scrapy: ``` pip install scrapy ``` 创建Scrapy项目 ----------------------- 创建Scrapy项目的命令是: ``` scrapy startproject project_name ``` 这个命令将会在当前目录下创建一个名为project_name的文件夹,其中包含了Scrapy项目的基本结构。 编写Spider ----------------------- 在Scrapy中,Spider是用来定义爬取网站的规则的。我们可以通过以下命令来创建一个Spider: ``` scrapy genspider spider_name domain_name ``` 其中,spider_name是我们自己定义的Spider名称,domain_name是我们要抓取的网站域名。 接下来,我们需要在Spider中定义如何爬取网站。这里我们以爬取“http://quotes.toscrape.com/”网站上的名言警句为例。我们可以在Spider中定义如下规则: ```python import scrapy class QuotesSpider(scrapy.Spider): name = "quotes" start_urls = [ 'http://quotes.toscrape.com/page/1/', 'http://quotes.toscrape.com/page/2/', ] def parse(self, response): for quote in response.css('div.quote'): yield { 'text': quote.css('span.text::text').get(), 'author': quote.css('span small::text').get(), 'tags': quote.css('div.tags a.tag::text').getall(), } next_page = response.css('li.next a::attr(href)').get() if next_page is not None: yield response.follow(next_page, self.parse) ``` 在上述代码中,我们首先定义了Spider的名称,接着定义了我们要爬取的起始URL,最后定义了如何解析网页的函数parse()。在parse()函数中,我们使用了Scrapy的选择器来提取网页中的名言警句,并将其保存到字典中。接着,我们使用response.follow()函数来获取下一页的URL,并继续解析。 运行Spider ----------------------- 要运行我们刚才创建的Spider,我们可以使用以下命令: ``` scrapy crawl spider_name ``` 其中,spider_name是我们之前创建的Spider名称。 Scrapy会自动去抓取我们定义的起始URL,并根据我们定义的规则来解析网页。解析完成后,Scrapy会将结果保存到我们指定的位置。 总结 ----------------------- Scrapy是一个非常强大的Python爬虫框架,它可以帮助我们快速高效地抓取网站数据。在本教程中,我们介绍了Scrapy项目的创建、Spider的定义以及如何运行Spider。如果您想更深入地学习Scrapy,可以参考官方文档:https://docs.scrapy.org/en/latest/。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值