1.CrawlSpider类通过一些规则(rules),使对于链接(网页)的爬取更具有通用性,
换句话说,CrawlSpider爬虫为通用性的爬虫,
而Spider爬虫更像是为一些特殊网站制定的爬虫。它基于Spider并有一些独特属性
rules: 是Rule对象的集合,用于匹配目标网站并排除干扰
parse_start_url: 用于爬取起始响应,必须要返回Item
2. Scrapy中的爬虫方法继承四种类来建立我们的scrapy爬虫,
他们是:Spider类,CrawlSpider类, CSVFeedSpider类和XMLFeedSpider类
3. 通过命令的方式生成一个CrawlSpider类的模板
scrapy genspider -t crawl 爬虫 域名
4. 通过爬取这个网站http://bxjg.circ.gov.cn/web/site0/tab5240/module14430/page1.htm 来使用CrawlSpider类进行爬虫
(1)创建好项目后,创建爬虫(加入了-t crawl) scrapy genspider -t crawl punish bxjg.circ.gov.cn
(2) 可以使用rules规则,就可以不用再写一个专门针对于下一页的请求函数了
rules = ( Rule(LinkExtractor(allow=r'/web/site0/tab5240/info\d+\.htm'), callback='parse_item'), Rule(LinkExtractor(allow=r'/web/site0/tab5240/module14430/page\d+\.htm'),follow=True), )
LinkExtractor 连接提取器,提取url
参数:
url allow : 可以写入正则表达式
callback: 提取出来的url地址的response交给callback处理 ,需要时再用,一般对应的网站详情页面要使用
follow: 表示当前的url地址的响应是否重新经过rules来提取url地址,需要时再用
(3) 然后 编写爬虫的代码
# -*- coding: utf-8 -*- import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule import re '''继承spider的crawlspider类''' class PunishSpider(CrawlSpider): name = 'punish' allowed_domains = ['bxjg.circ.gov.cn'] start_urls = ['http://bxjg.circ.gov.cn/web/site0/tab5240/module14430/page1.htm'] ''' 可以定义提取url地址的规则 LinkExtractor 连接提取器,提取url allow : 可以写入正则表达式 callback: 提取出来的url地址的response交给callback处理 follow: 表示当前的url地址的响应是否重新经过rules来提取url地址 ''' rules = ( Rule(LinkExtractor(allow=r'/web/site0/tab5240/info\d+\.htm'), callback='parse_item'), Rule(LinkExtractor(allow=r'/web/site0/tab5240/module14430/page\d+\.htm'),follow=True), ) '''与Spider类不同,CrawlSpider类中的parse函数有特殊功能,不能定义''' def parse_item(self, response): item = {} item['title'] = re.findall("<!--TitleStart-->(.*?)<!--TitleEnd-->",response.body.decode())[0] item['publish_date'] = re.findall("发布时间:(20\d{2}-\d{2}-\d{2})",response.body.decode())[0] print(item)
(4) 在setting.py里面设置 LOG_LEVEL = "WARNING" 以及开启并设置 USER_AGENT,然后在终端运行程序
scrapy crawl punish
(5) LinKExtractor更多常见的参数:
5. 再请求详情页的时候,我们也可以使用在Spider类中一样,
通过 yield scrapy.Request() 方法也可以实现,但是代码会写的比使用Crawlspider类中的多