# -*- coding: utf-8 -*-
import scrapy,re
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from crawlspider.items import CrawlspiderItem class CrawlspidersSpider(CrawlSpider):
name = 'CrawlSpiders'
allowed_domains = ['sbiquge.com']
start_urls = ['https://www.sbiquge.com/biqukan/'] rules = (
Rule(LinkExtractor(allow="/\d+?_\d+?/",unique=True),callback='parse_item',follow=False),
# 注意使用restricted_xpath提取链接的时候只能到标签就好了,千万不要到具体的标签属性,那叫画蛇添足。
# 这个rule实例有callback属性,那么它就是从所有下载到的response里面提取链接,并下载链接内容由回调函数处理数据
)
def parse_item(self, response): chap_list = response.xpath('.//*[@class="listmain"]/dl/dd')
for chapter in chap_list:
novel_name = chapter.xpath('//*[@id="book"]/div[1]/div/a[2]/text()').extract_first()
chapter_name = chapter.xpath('./a/text()').extract_first()
chapter_link = chapter.xpath('./a/@href').extract_first()
if chapter_name:
item = CrawlspiderItem(chapter_title=chapter_name,novel_name=novel_name)
url = response.urljoin(chapter_link)
request = scrapy.Request(url=url,callback=self.parse_body)
request.meta['key'] = item
yield request def parse_body(self,response):
item = response.meta['key']
content_list = response.xpath('.//*[@id="content"]').re('([\u4e00-\u9fa5]|<br>)+?') # 匹配到的是一个列表
# 利用re直接匹配小说的汉字内容.正则可以匹配标签下的任何内容,这样我们可以提取我们想要的数据
content_str = ''.join(content_list)
content = re.sub('<br><br>','\n ',content_str)
# 对匹配的章节进行分段
item['content'] = content
yield item
重点在于CrawlSpider的学习!!!!!!!!!!!!!
**通过前面的学习我们可以进行一些页面的简单自动话爬取,对于一些比较规则的网站,我们似乎可以用Spider类去应付,可是,对于一些较为复杂或者说链接的存放不规则的网站我们该怎么去爬取呢,接下来的爬虫就是要解决这个问题,而且还可以高度的自动化爬取链接和链接内容**
1
CrawlSpider类,是建立爬虫的另外一个类。
*(顺便说一下,我们可以继承四种类来建立我们的scrapy爬虫,他们是:Spider类,CrawlSpider类, CSVFeedSpider类和XMLFeedSpider类,今天我们讲的就是CrawlSpider类建立的爬虫)*
1
CrawlSpider类通过一些规则(rules),使对于链接(网页)的爬取更具有通用性,换句话说,CrawlSpider爬虫为通用性的爬虫,而Spider爬虫更像是为一些特殊网站制定的爬虫。
那我们开始正式的讲解一下CrawlSpider爬虫。。。。
首先我们建立一个爬虫工程:
scrapy startproject crawlspider
1
这个我们很熟悉,接下来创建一个CrawlSpider爬虫
scrapy genspider -t crawl Crawlspider domain.com
1
注意上面,我们比Spider爬虫建立时多了一个’-t crawl’,这是值爬虫的类
这样以后我们就可以在我们的spiders文件中找到这个爬虫
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
class CrawlspiderSpider(CrawlSpider):
name = 'crawlspider'
allowed_domains = ['domain.com']
start_urls = ['http://domain.com/']
rules = (
Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
)
def parse_item(self, response):
i = {}
#i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract()
#i['name'] = response.xpath('//div[@id="name"]').extract()
#i['description'] = response.xpath('//div[@id="description"]').extract()
return i
上面是打开爬虫后,自动生成的一段代码,这段代码可以说基本上对于CrawlSpider爬虫的结构有一个构造,我们看到,有一个rules属性,还有这个爬虫继承的类是CrawlSpider,这两点就是与前几篇讲的Spider爬虫的区别。其中rules属性使这个爬虫的核心
所以我们在开始讲我们的实战项目之前我们应该先讲一下这个rules属性。
rules属性由几个Rule对象构成,而Rule对象定义了提取链接等操作的规则
那么Rule的构造又是怎样的呢?
Rule对象有六个属性,他们分别是:
LinkExtractor(…),用于提取response中的链接
callback=‘str’,回调函数,对提取的链接使用,用于提取数据填充item
cb_kwargs,传递给回调函数的参数字典
follow=True/False,对提取的链接是否需要跟进
process_links,一个过滤链接的函数
process_request,一个过滤链接Request的函数
上面的参数除了LinkExtractor外其它都是可选的,且当callback参数为None时,我们称这个rule为一个‘跳板’,也就是只下载页面,并不进行任何行为,通常作翻页功能
我们需要解释主要是LinkExtractor参数和follow参数:
一、LinkExtractor参数,明显是用来提取链接的。那么他是怎么来定义提取链接的规则的呢?它有十个参数,用来定义提取链接的规则,分别是:
1. allow=‘re_str’:正则表达式字符串,提取response中符合re表达式的链接。
2. deny=‘re_str’:排除正则表达式匹配的链接
3. restrict_xpaths=‘xpath_str’:提取满足xpath表达式的链接
4. restrict_css=‘css_str’:提取满足css表达式的链接
5. allow_domains=‘domain_str’:允许的域名
6. deny_domains=‘domain_str’:排除的域名
7. tags=‘tag’/[‘tag1’,’tag2’,…]:提取指定标签下的链接,默认会从a和area标签下提取链接
8. attrs=[‘href’,’src’,…]:提取满足属性的链接
9. unique=True/False:链接是否去重
10.process_value:值处理函数,优先级要大于allow
以上的参数可以一起使用,以提取同时满足条件的链接
二、follow参数:
为Boolean值,用于是否跟进链接的处理,在callback为None时,默认是跟进链接的,值为True;当callback不为空时,默认是False的,不跟进链接。当然我们可以根据需要赋值,
那么,什么叫跟进,什么叫不跟进呢?
就是你前面定义的规则对于已经提取到的链接的页面是不是在进行一次提取链接。
1
2
好!那么rules到底是怎么工作的呢?
这样的,对于Rule提取的链接会自动调用parse函数,并返回该链接的response,然后将这个response给callback回调函数,通过回调函数的解析对item进行填充
对了,CrawlSpider爬虫还有一个parse_start_url()方法,用于解析start_urls中的链接页面,这个方法一般用于有跳板的爬虫中,用于对首页的解析
说了那么多,我们来说说我们的爬虫项目。用CrawlSpider爬虫,爬取整站的小说