优化scrapy爬虫

作者: baixiao 分类: python爬虫 发布时间: 2020-10-07 14:24

项目的复用

在千辛万苦配置好Scrapy项目文件之后,同样的过程不想再输入一遍,配置这些东西都好繁琐和无聊。我以前重复同样的项目配置,一个爬虫下来得调试个一个多小时已经算快的了,毕竟框架好多地方需要修改。

以爬取小说网站为例,不同地方在于提取标题、网址Url、内容的xpath不一样,即只是spiders文件夹下爬虫文件不一样而已。

novel_xx
├── novel_xx
│   ├── __init__.py
│   ├── items.py
│   ├── middlewares.py
│   ├── pipelines.py
│   ├── settings.py
│   └── spiders
│       └── __init__.py
└── scrapy.cfg

而且生成爬虫的命令scrapy genspider xx_spider yy.com是产生xx_spider名字的爬虫,其对应小说网站yy.com域名,并在spiders文件夹内产生xx_spider.py文件。

在工程中可以产生一个或多个spider,在spiders文件夹内产生不同名字的.py文件。

这样可以复用Items.pypipelines.pysettings.py等文件,即工程大部分可以复用不用修改了,这样节省了好多时间和避免额外带来很多不必要的错误和调试时间。

爬虫设置

爬虫设置在settings.py中,包括以下方面:

# 是否遵循爬虫机器人
ROBOTSTXT_OBEY = False

# 并发是指同时处理的request的数量,调整其建议达到CPU 80%,默认16
CONCURRENT_REQUESTS = 100

# 正式爬取中只显示INFO级别信息,Debug级别信息只在开始调试使用
LOG_LEVEL = 'INFO'
# LOG_LEVEL = 'DEBUG'

# 如非必要,禁用Cookies加快爬取
COOKIES_ENABLED = False

# 修改默认请求头,主要是'USER_AGENT':
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
}

# 使用本地缓存,减少请求网站
HTTPCACHE_ENABLED = True
HTTPCACHE_EXPIRATION_SECS = 0
HTTPCACHE_DIR = 'httpcache'
HTTPCACHE_IGNORE_HTTP_CODES = []
HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
## 缓存策略
HTTPCACHE_POLICY='scrapy.extensions.httpcache.RFC2616Policy'
#针对生产环境并且应用在持续性运行环境所设置。该策略能避免下载未修改的数据(来节省带宽,提高爬取速度)。

# HTTPCACHE_POLICY='scrapy.extensions.httpcache.DummyPolicy'
# #对于测试spider十分有用。其能使spider运行更快(不需要每次等待下载完成), 同时在没有网络连接时也能测试。

# 爬虫暂停与恢复文件夹
JOBDIR='jobdir'

## 是否开启retry
RETRY_ENABLED=True
## 重试次数
RETRY_TIMES=10
## 遇到什么http code时需要重试,默认是500,502,503,504,408,其他的,网络连接超时等问题也会自动retry的
RETRY_HTTP_CODECS=[500,502,503,504,408,404]

合格的爬虫爬取标准

一般来说,现在一般的网站都几十万至上百万的页面去了,一般几千页面的小网站都摆不上台面了。(作为同样有着一个小网站的博主,这脸piapia地生疼。)

而且按照Scrapy bench的测试速度,Scrapy访问的是localhost能够达到3000页面/min,换算而言是18万/小时,一天大概是四五百万页面。当然了,这个是本地访问速度。如果页面多了之后就上分布式之类的。不过到了这么大规模之后,得考虑反爬虫的一些事情了。这个就扯远了。

一般来看,可以看自己爬虫CPU消耗、内存消耗、网络链接情况。一般自己CPU耗费50%,网络连接速度多大。一般文本500KiB/s已经算很大了,毕竟网站服务器带宽还是很贵的,从KiB/s换算为Mbps要乘以8,而且还不能影响正常用户访问,即爬取带宽占比不要过大,20%就挺好。另外爬取速度200页面/min,每小时过万页面,爬虫速度算是可以。当然了,最主要是看你要爬取完成的时间能否在一日内或几小时内完成。毕竟花个几天时间爬取,这个也是很冗长的流程了。

一般来说,影响爬虫的一些因素有:

网站链接速度,同样的网站,挂了代理和没有代理差别还是挺大 的;还有一些小网站出口带宽就那么一点点,比如说常见的10Mbps带宽,还有一些入门级的1Mbps那就洗洗睡了(在国内服务器带宽小的离谱一大帮站长集体脸piapia地疼)。

网站服务器的性能,比如说有一些小网站就是很弱弱的单核CPU,你爬虫多核都80%了,对方服务器岂不是100%爆炸了。所以为什么要尽量晚上爬取,白天正常访问高峰时候抢占资源已经妨碍了正常访问用户,也阻碍了自己爬取速度。

另外为什么用Scrapy框架的地方在于,在爬取过程中会显示很多数据和进度,方便监控爬虫。自己用Aiohttp和线程池+requests的方法,很多时候对爬虫进度并不是那么直观。Scrapy结束的时候会有一个统计,统计成功爬取页面,耗时之类的,清楚直观。以下面为例,总计爬取了8401页面(downloader/request_count),耗时1151s(elapsed_time_seconds),下载量198MB(response_bytes),相当于每小时2万多张页面。

[scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 3769023,
'downloader/request_count': 8401,
'downloader/request_method_count/GET': 8401,
## 下载量字节大小B
'downloader/response_bytes': 198638509,
## 爬取页面数量
'downloader/response_count': 8401,
'downloader/response_status_count/200': 8401,
## 下载耗时
'elapsed_time_seconds': 1151.568491,
'finish_reason': 'finished',
'finish_time': datetime.datetime(2020, 8, 23, 3, 4, 15, 712938),
'httpcache/firsthand': 8401,
'httpcache/miss': 8401,
'httpcache/uncacheable': 8401,
'item_scraped_count': 7975,
'log_count/ERROR': 24,
'log_count/INFO': 8406,
'memusage/max': 91279360,
'memusage/startup': 52350976,
'request_depth_max': 1,
'response_received_count': 8401,
'scheduler/dequeued': 8401,
'scheduler/dequeued/disk': 8401,
'scheduler/enqueued': 8401,
'scheduler/enqueued/disk': 8401,
'start_time': datetime.datetime(2020, 8, 23, 2, 45, 4, 144447)}
[scrapy.core.engine] INFO: Spider closed (finished)

Scrapy运行越来越慢

我爬取一个大概10万以上页面的小说网站,刚开始时候能够达到1200页/min,一小时大概7万页面,号称一天能达百万量级的爬取规模(摊手状,毕竟牛皮容易吹嘛,所以要“号称”)。因为要下载下来小说来看,当时为了省事直接保存为txt文本文档。现在经历过这个事情之后,文本文档和数据库在大规模的访问速度有了相当直观的对比和明显,以后还是直接保存到数据库里吧。

但是到了后面就发现速度逐步往下走了,到后面曾经一度直接变成20页/min,这个就让我很诧异了,这个速度也太慢了。

查看一下,发现既不是网速问题,也不是CPU和内存占用问题,但是电脑操作也的确很卡,干什么都费劲。访问该项目文件夹速度很慢,当时还在纳闷是不是爬取的页面直接保存为txt下来直接把硬盘给写挂了?

还不得不利用CentOS7自带的硬盘读写速度软件进行测试。发现home分区测速正常;但是到了访问项目所在分区,读取速度就逐步往下了,到达一半的速度了。

home分区测速
项目所在分区windows D盘测速

随着缓存文件的加大,导致了.scrapy文件夹越发加大。导致访问该文件夹速度都很慢,因此打算把这个文件夹给清理掉。

.scrapy下面有httpcache文件夹,里面有不同爬虫对应的文件夹,每个文件夹下又分了众多页面文件夹,爬取到的页面的缓存,分别为pickled_metarequest_headersrequest_bodyresponse_headersresponse_body这五个部分。

因为在Scrapy爬虫是这么设置缓存的。

# 使用本地缓存,减少请求网站
HTTPCACHE_ENABLED = True
HTTPCACHE_EXPIRATION_SECS = 0
HTTPCACHE_DIR = 'httpcache'
HTTPCACHE_IGNORE_HTTP_CODES = []
HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
## 缓存策略
HTTPCACHE_POLICY='scrapy.extensions.httpcache.RFC2616Policy'
#针对生产环境并且应用在持续性运行环境所设置。该策略能避免下载未修改的数据(来节省带宽,提高爬取速度)。

# HTTPCACHE_POLICY='scrapy.extensions.httpcache.DummyPolicy'
# #对于测试spider十分有用。其能使spider运行更快(不需要每次等待下载完成), 同时在没有网络连接时也能测试。

真是不看不知道,一看吓一跳,整个文件夹居然有几十万个小文件,因为我爬取了大概7万张页面。导致了直接图形界面删除文件夹大半天都没啥反应。

删除scrapy缓存

后面直接用命令行删除,命令行如下

rm -rfv .scrapy/

其中,注意文件夹后面/斜杠。-r代表递归删除,删除掉文件夹及子文件架和文件;-f代表强制删除,不用反复提示选择y或者n;-v代表显示删除过程。用了这命令了 ,只见屏幕哗啦啦地一直滚动删除记录,几十万条也不是那么容易删除完毕的。后面估算了一下时间,刷屏估计时间会很久,直接把-v参数去掉,直到删除结束之后命令行光标才恢复。

作者的其他回答:

这篇服务器的使用经验帮助了近千人,简明实用,阐述到位。值得你花几分钟看一下。

[自己拥有一台服务器可以做哪些很酷的事情] (https://www.toutiao.com/i6830055688048214532/)

服务器建立个人网站,看看这个,少走弯路不买错,堪称完美避坑指南。

[阿里云服务器快速建网站 (安装BT宝塔面板和wordpress)] (https://www.toutiao.com/i6821887045569348107/)

朋友们都点赞的服务器选购指南,5分钟看一遍,能节约你4小时选购时间。

阿里云域名注册与备案、服务器ECS购买与登录 (https://www.toutiao.com/i6811104414296703496/)

[七牛图床添加阿里云域名] (https://www.toutiao.com/i6812523427614687747/)、

[markdown多平台发布及七牛图床使用] (https://www.toutiao.com/i6771402918026281486/)

还有好十几篇这么优秀的经验分享,都收在我个人回答里,关注我,你将获得不一样的经验。


阿里云推荐

架设个人博客网站、企业门户都可以使用ECS。如果其网站如个人博客主要面向国内用户访问,为加快速度还是建议选用国内的服务器商。

[阿里云域名] (https://wanwang.aliyun.com/domain/com/?userCode=yos4xyvp)连接,

[阿里云服务器ECS] (https://www.aliyun.com/minisite/goods?userCode=yos4xyvp) 链接

为什么选择阿里云

  1. 以前域名注册一般选老牌域名服务商,其中万网已经被阿里收购到旗下了。
  2. 提供域名备案服务。备案业务还是很贴心的。提交完备案信息之后,第二天阿里云小姐姐会帮你免费形式审查一下,还会主动打电话过来帮助校正。如果是自己动手提交备案信息给ICP备案机构,万一因为低级错误被驳回就浪费了十天左右时间。
  3. 域名ICP备案需要服务器,阿里云也提供服务器购买,一条龙服务嘛。服务器在阿里云毕竟服务器才是支出大头,域名什么的都是小意思了。而且购买完服务器之后,还会有客服主动打电话过来询问使用情况,需不需要技术支持,还是挺不错的。
  4. 阿里云服务器购买新用户有优惠,最基础的话一年下来不超过100元。如果是本科生的话免费使用的。
  5. 备案完成之前,服务器不算租赁时间。比如说3月1日我购买了一年的服务器,域名提交备案。18日域名备案审核通过。服务器租赁时间重新按18日算起,即可以用到第二年3月18日。相当于免费多用几天。占了一点小便宜。

云主机交流

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注