scrapy框架使用-crawlspider类,rule的使用,翻页功能,
###
在Scrapy基础——Spider中。Spider基本上能做很多事情了,但是如果你想爬取一个网站的全站的话,你可能需要一个更强大的武器。
CrawlSpider基于Spider,但是可以说是为全站爬取而生。
##
生成一个crawlspider的爬虫:
命令:scrapy genspider -t crawl spider2 "baidu.com"
之前创建的普通爬虫的命令:scrapy genspider spider1 baidu.com,多了一个-t crawl,
区别:
1,首先继承的父类就是不一样的,class Spider1Spider(scrapy.Spider): ------- class Spider2Spider(CrawlSpider):
2,多了一个rules,这个就是定义规则的地方,
第一个参数就是正则表达式,
第二个callback 不是一定要的,可以没有这个参数,因为提取出的url,不需要处理
第三个参数,在提取url的下一个页面是否需要再次按照前面的规则继续提取,
3,parse函数不见了,这个地方不能定义parse函数,这个函数有特殊的用处,
####
使用crawlspider翻页
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class Spider2Spider(CrawlSpider): name = 'spider2' allowed_domains = ['17k.com'] start_urls = ['https://www.17k.com/all/book/2_0_0_5_1_0_2_0_1.html'] rules = ( # Rule(LinkExtractor(allow=r'https://www.17k.com/book/\d+.html'), callback='parse_item'), Rule(LinkExtractor(allow=r'https://www.17k.com/all/book/2_0_0_5_1_0_2_0_\d+.html'), callback='parse_item', follow=True), ) def parse_item(self, response): print(response.url) ret = response.xpath("//table//td//span/a") # print(ret) for i in ret: item = {} # print(i.xpath('./text()').get()) # print(i.xpath('./@href').get()) item["title"] = i.xpath('./text()').get() item["href"] = "https:" + i.xpath('./@href').extract_first() # print(item) yield scrapy.Request( item["href"], callback=self.getDetail, meta={"item": item} ) def getDetail(self, response): # print(response.url) # print(response.meta["item"]) item = response.meta["item"] item["clickNum"] = response.xpath("//td[@id='hb_week']/text()").extract_first() print(item) yield item if __name__ == '__main__': from scrapy import cmdline cmdline.execute("scrapy crawl spider2 --nolog".split())
####
认识这个crawlspider方法:
1,这个rule,是非常关键的,这是重点!!!这个规则,是把所有的翻页url拿到了,然后callback,处理每一页,follow=True这是需要往下递归的,看情况是不是需要
2,其他的用法都是和spider类类似的,包括对管道的使用等,
####
关于对rule的使用
1,第一个参数,LinkExtractor(),就是一个提取器,里面就是你要提取的连接,
2,第二个参数,callback,这个回调函数,就是签名提取器的每一个连接,都会循环进入这个回调函数进行处理,
3,第三个参数,follow,这个是一个TRUE,或者FALSE,这个就是是否在提取的连接之后,继续往下提取,
这个参数很重要,比如100页,可以帮我们一直爬取到100页,而且是去重的url,
4,这个rules,是可以有多个规则的,但是使用的道理都是一样的,而且不同规则之后提取出来来的url,也会进行去重,这个很厉害了,好吧,
5,另外你要知道,可以有多个回调函数的,
6,这个rule一定要有,否则这个代码是跑不起来的,
######
对这个链接提取器的理解,
import scrapy from scrapy.linkextractors import LinkExtractor class Spider6Spider(scrapy.Spider): name = 'spider6' allowed_domains = ['17k.com'] start_urls = ['https://www.17k.com/all/book/2_0_0_5_1_0_2_0_1.html'] def parse(self, response): print(response) # pageurl = LinkExtractor(r'https://www.17k.com/all/book/2_0_0_5_1_0_2_0_\d+.html') # pageurl = LinkExtractor() pageurl = LinkExtractor(allow=r"2_0_0_5_1_0_2_0_\d") # print(pageurl.extract_links(response)) # 这是一个列表 print(type(pageurl.extract_links(response)[0])) # <class 'scrapy.link.Link'> print([i.url for i in pageurl.extract_links(response)]) if __name__ == '__main__': from scrapy import cmdline cmdline.execute("scrapy crawl spider6 --nolog".split())
####
可见,
1,这个连接提取器是可以单独使用的,
2,如果提取器里面不写正则,就是提取所有的url,这个要注意,
3,另外pageurl.extract_links(response)这个用法,要知道,
4,这是返回了一个列表,
5,列表里面是一个link类型的东西,可以通过.url,.text,把内容拿出来,就可以单独使用了,这个就不用自己写了,
其中的link_extractor既可以自己定义,也可以使用已有LinkExtractor类,主要参数为:
allow:满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。
deny:与这个正则表达式(或正则表达式列表)不匹配的URL一定不提取。
allow_domains:会被提取的链接的domains。
deny_domains:一定不会被提取链接的domains。
restrict_xpaths:使用xpath表达式,和allow共同作用过滤链接。还有一个类似的restrict_css
所以现在对这个提取器还是有了更进一步的认识了,
##
通过这个crawlspider是可以爬取全站数据的,
就是把这个连接提取器为空,就是提取所有的url,就可以一直爬取下去了,
比如爬取天涯网站上面所有的邮箱,这就厉害了,
比如爬取百度百科所有的词条,这个也是有价值的,
####
所以你使用普通的spider写一个单页的爬虫,
然后修改继承的类,增加rule就可以进行多页的爬虫,甚至是全站的爬虫,
这就是框架牛逼的地方,
####
实战阳光问政,这个有ip反爬,我正好用这个练练手,
###
现在爬17k
###
代码:
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class Spider2Spider(CrawlSpider): name = 'sun' allowed_domains = ['17k.com'] start_urls = ['https://www.17k.com/all/book/2_0_0_5_1_0_2_0_1.html'] rules = ( # 翻页 Rule(LinkExtractor(allow=r'https://www.17k.com/all/book/2_0_0_5_1_0_2_0_\d+.html')), # 详情页 Rule(LinkExtractor(allow=r'https://www.17k.com/book/\d+.html'), callback='getDetail'), ) def parse_item(self, response): print(response.url) def getDetail(self, response): book_info = response.xpath("//p[@class='intro']/a/text()").getall() print(book_info) print("##############") if __name__ == '__main__': from scrapy import cmdline cmdline.execute("scrapy crawl sun --nolog".split())
###
这个就是实现了自动翻页,而没有回调函数,Rule(LinkExtractor(allow=r'https://www.17k.com/all/book/2_0_0_5_1_0_2_0_\d+.html')),
###
####
相关文章
- 第三百四十节,Python分布式爬虫打造搜索引擎Scrapy精讲—css选择器
- 第三百三十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—深度优先与广度优先原理
- 第三百三十五节,web爬虫讲解2—Scrapy框架爬虫—豆瓣登录与利用打码接口实现自动识别验证码
- 第三百三十一节,web爬虫讲解2—Scrapy框架爬虫—Scrapy安装—Scrapy指令
- scrapy框架使用-爬虫中间件
- 小白学 Python 爬虫(41):爬虫框架 Scrapy 入门基础(八)对接 Splash 实战
- 小白学 Python 爬虫(38):爬虫框架 Scrapy 入门基础(六) Item Pipeline
- 小白学 Python 爬虫(36):爬虫框架 Scrapy 入门基础(四) Downloader Middleware
- 小白学 Python 爬虫(33):爬虫框架 Scrapy 入门基础(一)
- scrapy框架使用-爬虫中间件
- scrapy框架使用-scrapy-redis的使用,通过requests去重实现增量式爬虫,使用redisspider实现分布式爬虫
- scrapy框架使用-下载中间件,在下载中间件里面,添加随机UA,添加随机代理ip,这个很重要
- scrapy框架使用-模拟登陆,使用cookie登陆,使用post登陆,使用selenium模拟登陆
- 在scrapy中使用mongodb管道
- scrapy settings值的含义
- python爬虫:scrapy框架xpath和css选择器语法
- Python爬虫:Scrapy链接解析器LinkExtractor返回Link对象
- Python爬虫:scrapy框架请求参数meta、headers、cookies一探究竟
- Python爬虫:关于scrapy、Gerapy等爬虫相关框架和工具
- 爬虫日记(76):Scrapy的命令行源码分析二
- 爬虫日记(16):scrapy特殊功能的蜘蛛类
- Scrapy框架之高级 转
- scrapy-下载器中间件 随机切换user_agent
- Crawler之Scrapy:基于scrapy框架实现爬虫两个网址下载网页内容信息之详细攻略
- 从零开始,学会Python爬虫不再难!!! -- (14)Scrapy框架丨蓄力计划