一、如何提升scrapy框架的爬取效率

  增加并发: 默认scrapy开启的并发线程为32个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100,并发设置成了为100。

  降低日志级别: 在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:LOG_LEVEL = 'INFO'。

  禁止cookie: 如果不是真的需要cookie,则在scrapy爬取数据时可以禁止cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写:COOKIES_ENABLED = False。

  禁止重试: 对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:RETRY_ENABLED = False。

  减少下载超时: 如果对一个非常慢的链接进行爬取,减少下载超时可以让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写:DOWNLOAD_TIMEOUT = 10 ,超时时间为10s。

二、CrawlSpider

  参考博客:https://www.cnblogs.com/bobo-zhang/p/9670764.html

1、介绍

  CrawlSpider其实是Spider的一个子类,除了继承到Spider的特性和功能外,还派生出了自己独有的更加强大的特性和功能。其中最显著的功能就是"LinkExtractors链接提取器"。Spider是所有爬虫的基类,其设计原则只是为了爬取start_url列表中网页,而从爬取到的网页中提取出的url进行继续的爬取工作使用CrawlSpider更合适。

2、使用

1)案例一:爬取抽屉网段子模块(https://dig.chouti.com/r/scoff/hot/1)第一页到最后一页的数据的标题

  新建一个项目:scrapy startproject choutiPro

  进入项目目录下,新建一个爬虫文件:scrapy genspider -t crawl chouti www.xxx.com

  注意:生成爬虫文件的指令多了 "-t crawl",表示创建的爬虫文件是基于CrawlSpider这个类的,而不再是Spider这个基类,生成的爬虫文件内容如下:

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule class ChoutiSpider(CrawlSpider):
name = 'chouti'
allowed_domains = ['www.xxx.com']
start_urls = ['http://www.xxx.com/'] rules = (
Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
) def parse_item(self, response):
item = {}
#item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
#item['name'] = response.xpath('//div[@id="name"]').get()
#item['description'] = response.xpath('//div[@id="description"]').get()
return item

  项目的目录结构如下:

  各文件内容如下:

# choutiPro/choutiPro/spiders/chouti.py

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule class ChoutiSpider(CrawlSpider):
name = 'chouti'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://dig.chouti.com/r/scoff/hot/1'] # 链接提取器,参数 allow表示链接提取器提取链接的规则(正则)
link = LinkExtractor(allow=r'/r/scoff/hot/\d+')
# 让链接提取器继续作用到提取到的链接所对应的页面中
rules = (
# 规则解析器:将链接提取器提取到的链接所对应的页面数据进行指定形式的解析,注意follow要等于True
Rule(link, callback='parse_item', follow=True),
) def parse_item(self, response):
     print(response)  
# div_list = response.xpath('//div[@class="item"]')
# for div in div_list:
# title = div.xpath('.//div[@class="part1"]/a/text()').extract_first()
# print(title)

  注意修改settings.py中的USER_AGENT和ROBOTSTXT_OBEY。

  启动程序,如下图:

2)案例二:爬取糗事百科的糗图模块(https://www.qiushibaike.com/pic/)所有页码的数据

  使用上面案例一的项目,修改爬虫文件 chouti.py文件为如下内容:

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule class ChoutiSpider(CrawlSpider):
name = 'qiubai'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://www.qiushibaike.com/pic/'] link = LinkExtractor(allow=r'/pic/page/\d+\?s=\d+')
link1 = LinkExtractor(allow=r'/pic/$') rules = (
Rule(link, callback='parse_item', follow=True),
Rule(link1, callback='parse_item', follow=True),
) def parse_item(self, response):
print(response)

  启动项目,如下图:

三、分布式爬虫

  参考博客:https://www.cnblogs.com/bobo-zhang/p/9686978.html

  思考:

    为什么原生的scrapy不能实现分布式?

      - 调度器不能被共享;

      - 管道无法被共享;

    scrapy-redis组件的作用是什么?

      - 提供了可以被共享的调度器和管道;

1、下载安装scrapy-redis

  pip3 install scrapy-redis

2、使用流程

  1)创建工程:scrapy startproject redisChoutiPro

  2)进入工程,创建爬虫文件:scrapy genspider -t crawl chouti www.xxx.com

    目录结构如下:

  3)对爬虫文件,即spiders/chouti.py文件中的相关属性进行修改:

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_redis.spiders import RedisCrawlSpider # 导包 class ChoutiSpider(RedisCrawlSpider): # 修改继承的类
name = 'chouti'
# allowed_domains = ['www.xxx.com']
# start_urls = ['http://www.xxx.com/']
redis_key = 'chouti' # 调度器队列的名称 ......

  4)在配置文件,即settings.py中进行配置如下参数:

# - 使用组件中封装好的可以被共享的管道类
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 400
} # - 配置调度器(即使用组件中封装好的可以被共享的调度器)
# 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
SCHEDULER_PERSIST = True # 数据指纹

  5)指定存储数据的redis,即在settings.py文件中配置如下参数:

REDIS_HOST = 'redis服务的ip地址'
REDIS_PORT = 6379

  6)配置redis数据库的配置文件

protected-mode no      # 取消保护模式
# bind 127.0.0.1 # 取消bind绑定

  7)启动redis

  8)写好爬虫文件的功能后,启动爬虫文件(进入spiders目录下执行):scrapy runspider chouti.py

    爬虫文件chouti.py内容如下:

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from redisChoutiPro.items import RedischoutiproItem
from scrapy_redis.spiders import RedisCrawlSpider # 导包 class ChoutiSpider(RedisCrawlSpider): # 修改继承的类
name = 'chouti'
# allowed_domains = ['www.xxx.com']
# start_urls = ['http://www.xxx.com/']
redis_key = 'chouti' # 调度器队列的名称 rules = (
Rule(LinkExtractor(allow=r'/all/hot/recent/\d+'), callback='parse_item', follow=True),
) def parse_item(self, response):
div_list = response.xpath('//div[@class="item"]')
for div in div_list:
title = div.xpath('./div[4]/div[1]/a/text()').extract_first()
author = div.xpath('./div[4]/div[2]/a[4]/b/text()').extract_first()
item = RedischoutiproItem()
item['title'] = title
item['author'] = author yield item

    注意配置setting.py中的USER_AGENT和ROBOTSTXT_OBEY参数。

  9)向调度器队列中扔入一个起始url,即在redis-cli中执行如下命令:

四、增量式爬虫

  参考博客:https://www.cnblogs.com/bobo-zhang/p/10373942.html

1、案例一:对url去重

  需求:爬取4567tv网站中所有的电影详情数据

  创建项目,目录结构如下:

  各文件内容如下:

# 爬虫文件movie.py

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from increment1_Pro.items import Increment1ProItem
from redis import Redis class MovieSpider(CrawlSpider):
name = 'movie'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://www.4567tv.tv/index.php/vod/show/id/7.html'] rules = (
Rule(LinkExtractor(allow=r'/index.php/vod/show/id/7/page/\d+\.html'), callback='parse_item', follow=True),
) def parse_item(self, response):
conn = Redis(host='127.0.0.1', port=6379)
detail_url_list = response.xpath('//li[@class="col-md-6 col-sm-4 col-xs-3"]/div/a/@href').extract()
for url in detail_url_list:
url = 'https://www.4567tv.tv' + url
ex = conn.sadd('movies_url',url)
# ex == 1 表示set中没有存储url
if ex == 1:
yield scrapy.Request(url=url, callback=self.parse_detail)
else:
print('网站没有更新数据,暂无新数据可爬取!') def parse_detail(self, response):
item = Increment1ProItem()
item['name'] = response.xpath('/html/body/div[1]/div/div/div/div[2]/h1/text()').extract_first()
item['actor'] = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[3]/a/text()').extract_first() yield item
# 管道文件pipelines.py

from redis import Redis

class Increment1ProPipeline(object):

    conn = None

    def open_spider(self, spider):
self.conn = Redis(host='127.0.0.1', port=6379) def process_item(self, item, spider):
print('有新数据被爬取到,正在入库......')
self.conn.lpush('movie_data', item)
return item
# items.py文件

import scrapy

class Increment1ProItem(scrapy.Item):
name = scrapy.Field()
actor = scrapy.Field()

  注意:settings.py中配置好ROBOTSTXT_OBEY、USER_AGENT和管道参数ITEM_PIPELINES。

2、案例二:对内容去重

  需求:爬取糗事百科中的段子和作者数据

  创建项目,目录结构如下:

  各文件结构如下:

# 爬虫文件 qiubai.py

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule from increment2_Pro.items import Increment2ProItem
from redis import Redis
import hashlib class QiubaiSpider(CrawlSpider):
name = 'qiubai'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://www.qiushibaike.com/text/'] rules = (
Rule(LinkExtractor(allow=r'/text/page/\d+/'), callback='parse_item', follow=True),
) def parse_item(self, response):
div_list = response.xpath('//div[@class="article block untagged mb15 typs_hot"]')
conn = Redis(host='127.0.0.1', port=6379) for div in div_list:
item = Increment2ProItem()
item['content'] = div.xpath('.//div[@class="content"]/span//text()').extract()
item['content'] = ''.join(item['content'])
item['author'] = div.xpath('./div/a[2]/h2/text() | ./div[1]/span[2]/h2/text()').extract_first()
source = item['author'] + item['content']
# 自己制定了一种形式的数据指纹
hashValue = hashlib.sha256(source.encode()).hexdigest() ex = conn.sadd('qiubai_hash', hashValue)
if ex == 1:
yield item
else:
print('没有更新数据要爬取!')
# 管道文件 pipelines.py

from redis import Redis

class Increment2ProPipeline(object):

    conn = None

    def open_spider(self, spider):
self.conn = Redis(host='127.0.0.1', port=6379) def process_item(self, item, spider):
dic = {
'author': item['author'],
'content': item['content']
}
self.conn.lpush('qiubaiData', dic)
print('爬取到一条数据,正在入库......')
return item
# items.py文件

import scrapy

class Increment2ProItem(scrapy.Item):
content = scrapy.Field()
author = scrapy.Field()

  注意:settings.py中配置好ROBOTSTXT_OBEY、USER_AGENT和管道参数ITEM_PIPELINES。

  第一次启动爬虫文件如下图:

  马上再次启动如下图:

  过十分钟再次启动如下图:

  

  

Scrapy框架(3)的更多相关文章

  1. Python爬虫Scrapy框架入门(2)

    本文是跟着大神博客,尝试从网站上爬一堆东西,一堆你懂得的东西 附上原创链接: http://www.cnblogs.com/qiyeboy/p/5428240.html 基本思路是,查看网页元素,填写 ...

  2. Python爬虫Scrapy框架入门(1)

    也许是很少接触python的原因,我觉得是Scrapy框架和以往Java框架很不一样:它真的是个框架. 从表层来看,与Java框架引入jar包.配置xml或.property文件不同,Scrapy的模 ...

  3. Scrapy框架使用—quotesbot 项目(学习记录一)

    一.Scrapy框架的安装及相关理论知识的学习可以参考:http://www.yiibai.com/scrapy/scrapy_environment.html 二.重点记录我学习使用scrapy框架 ...

  4. Python爬虫从入门到放弃(十一)之 Scrapy框架整体的一个了解

    这里是通过爬取伯乐在线的全部文章为例子,让自己先对scrapy进行一个整理的理解 该例子中的详细代码会放到我的github地址:https://github.com/pythonsite/spider ...

  5. Python爬虫从入门到放弃(十二)之 Scrapy框架的架构和原理

    这一篇文章主要是为了对scrapy框架的工作流程以及各个组件功能的介绍 Scrapy目前已经可以很好的在python3上运行Scrapy使用了Twisted作为框架,Twisted有些特殊的地方是它是 ...

  6. python爬虫scrapy框架——人工识别登录知乎倒立文字验证码和数字英文验证码(2)

    操作环境:python3 在上一文中python爬虫scrapy框架--人工识别知乎登录知乎倒立文字验证码和数字英文验证码(1)我们已经介绍了用Requests库来登录知乎,本文如果看不懂可以先看之前 ...

  7. 一个scrapy框架的爬虫(爬取京东图书)

    我们的这个爬虫设计来爬取京东图书(jd.com). scrapy框架相信大家比较了解了.里面有很多复杂的机制,超出本文的范围. 1.爬虫spider tips: 1.xpath的语法比较坑,但是你可以 ...

  8. 安装scrapy框架的常见问题及其解决方法

    下面小编讲一下自己在windows10安装及配置Scrapy中遇到的一些坑及其解决的方法,现在总结如下,希望对大家有所帮助. 常见问题一:pip版本需要升级 如果你的pip版本比较老,可能在安装的过程 ...

  9. 关于使用scrapy框架编写爬虫以及Ajax动态加载问题、反爬问题解决方案

    Python爬虫总结 总的来说,Python爬虫所做的事情分为两个部分,1:将网页的内容全部抓取下来,2:对抓取到的内容和进行解析,得到我们需要的信息. 目前公认比较好用的爬虫框架为Scrapy,而且 ...

  10. 利用scrapy框架进行爬虫

    今天一个网友问爬虫知识,自己把许多小细节都忘了,很惭愧,所以这里写一下大概的步骤,主要是自己巩固一下知识,顺便复习一下.(scrapy框架有一个好处,就是可以爬取https的内容) [爬取的是杨子晚报 ...

随机推荐

  1. SharePoint 2013 一次性上传文件大小限制

    默认是250MB,最大一次上传文件不超过2G The defaut size is 250MB and maximun upload size is 2047MB. It's can't greate ...

  2. Cookie管理工具

    Cookie Editor 是管理 Cookie 的工具,能识别并编辑IE.Firfox.Netscope Cookie 文件,控制个人隐私信息,修改 Cookie 使用期限,删除历史文件,编辑和删除 ...

  3. Canny边缘检测——学习笔记

    Sobel Canny 非极大值抑制NMS,上表为角度,下表为灰度 26度,在0-45°之间,离45°更近. 把不是极大值的点改为0,这样边缘会细很多. 双阈值判定 深度优先遍历

  4. Java精选笔记_JSP开发模型

    JSP开发模型 JSP Model JSP Model1简单轻便,适合小型Web项目的快速开发. JSP Model2模型是在JSP Model1的基础上提出的,它提供了更清晰的代码分层,更适用于多人 ...

  5. swift开发之--UISearchBar的使用/UISearchController的使用

    记录下UISearchBar的基本用法,补充:ios 8.0以后,原来的UISearchDisplayController被官方废弃,建议使用UISearchController,下面就简单的记录下这 ...

  6. X-code 描述文件的位置

    不管是真机测试还是打包的过程中,都需要描述文件.在桌面上,按快捷键“commd+Shift+G”,就会显示一个要填的文件路径,如下图: 找到描述文件的路径: ~/Library/MobileDevic ...

  7. python2.0_s12_day19_前端结合后端展示客户咨询纪录

    接下来就是将后台视图与前端页面结合起来了完成后台系统了.实现前端展示用户列表1.先在base.html代码中把模版中Dashboard下面的内容清空,如下: 具体删除哪些html代码,自己找吧.2.我 ...

  8. org.apache.ibatis.builder.IncompleteElementException: Could not find parameter map com.hyzn.historicalRecord.dao.ITB_HISTORYLOGDAO.TB_HISTORYLOGResultMap

    用了很久的myBatis,忽然出现这个错误,感觉配置什么的都是正确的,错误如下: org.apache.ibatis.builder.IncompleteElementException: Could ...

  9. UE4读取脑电波MindWave插件(展示如何使用第三方库制作UE4插件)

    MyEEGPlugin.uplugin { , , "VersionName": "1.0", "FriendlyName": " ...

  10. docker n2n安装与调试

    docker n2n安装与调试 yum install -y docker docker pull pahud/n2n-docker cd / 10 mkdir data 11 cd data 12 ...