crawlSpider全站爬取 分布式
# 如何提升scrapy爬取数据的效率?
推荐: 单线程加异步协程
增加并发:
默认scrapy开启的并发线程为32个,可以适当进行增加。在settings.py中修改
CONCURRENT_REQUESTS = 100
降低日志级别:
在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。
LOG_LEVEL = ‘INFO’ 或 'ERROR'
禁止cookie: 如果不是真的需要cookie,则在scrapy爬取数据时可以进制cookie从而减少CPU的使用率,提升爬取效率。
COOKIES_ENABLED = False
禁止重试:
对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。
RETRY_ENABLED = False
减少下载超时:
如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。DOWNLOAD_TIMEOUT = 10 超时时间为10s
# 配置文件
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36' ROBOTSTXT_OBEY = False # 遵守robots协议
CONCURRENT_REQUESTS = 100 #线程
COOKIES_ENABLED = False # cookie处理
LOG_LEVEL = 'ERROR' # 日志等级
RETRY_ENABLED = False # 重试
DOWNLOAD_TIMEOUT = 3 # 超时
DOWNLOAD_DELAY = 3 #下载延迟 一个个 类似sleep
# crawlSpider 是 Spider的一个子类
- crawlSpider全站数据爬取
- crawlSpider就是spider一个子类(派生)
- crawlSpider具有的机制:
- 链接提取器 LinkExtractors链接提取器
- 规则解析器 根据链接提取器中提取到的链接,根据指定规则提取解析器链接网页中的内容。
- 创建爬虫文件:
- 深度爬取:
# 创建一个工程
创建工程 scrapy startproject projectName
切换目录 cd projectName
创建爬虫 scrapy genspider -t crawl spiderName www.xxx.com
此指令对比以前的指令多了 "-t crawl",表示创建的爬虫文件是基于CrawlSpider这个类的,而不再是Spider这个基类
# 爬虫.py
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
class CrawlSpider(CrawlSpider):
name = 'c'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://www.qiushibaike.com/text/']
# 链接提取器:可以根据指定规则进行连接的提取
# allow表示的就是提取连接规则:正则
link = LinkExtractor(allow=r'') # 一层层全取得链接
link = LinkExtractor(allow=r'/text/page/\d+/')
link1 = LinkExtractor(allow=r'/text/')
rules = (
#规则解析器:根据指定规则进行响应数据的解析
#follow:将连接提取器继续作用到连接提取器提取出的连接所对应的页面源码中
Rule(link, callback='parse_item', follow=True),
Rule(link1, callback='parse_item'),
)
#回调函数调用的次数是由连接提取器提取连接个数决定
def parse_item(self, response):
print(response)
--------------------------------------------------------
LinkExtractor(
allow=r'Items/',# 满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。
deny=xxx, # 满足正则表达式的则不会被提取。
restrict_xpaths=xxx, # 满足xpath表达式的值会被提取
restrict_css=xxx, # 满足css表达式的值会被提取
deny_domains=xxx, # 不会被提取的链接的domains。
)
# 下面是BOSS直聘 页面及详情页的数据获取
# spider.py
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from bossPro.items import DetailItem,FirstItem
# 爬取的是岗位名称(首页)和 岗位描述(详情页)
class BossSpider(CrawlSpider):
name = 'boss'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://www.zhipin.com/c101010100/?query=python%E5%BC%80%E5%8F%91&page=1&ka=page-prev']
# 获取所有的页码link
link = LinkExtractor(allow=r'page=\d+')
link_detail = LinkExtractor(allow=r'/job_detail/.*?html')
#/job_detail/f2a47b2f40c53bd41XJ93Nm_GVQ~.html
#/job_detail/47dc9803e93701581XN80ty7GFI~.html
rules = (
Rule(link, callback='parse_item', follow=True),
Rule(link_detail, callback='parse_detail'),
)
#将页码连接对应的页面数据中的岗位名称进行解析
def parse_item(self, response):
# print(response)
li_list = response.xpath('//div[@class="job-list"]/ul/li')
for li in li_list:
item = FirstItem() # 实例化
job_title = li.xpath('.//div[@class="job-title"]/text()').extract_first()
item['job_title'] = job_title
print(job_title)
yield item
def parse_detail(self,response):
# print(response)
job_desc = response.xpath('//*[@id="main"]/div[3]/div/div[2]/div[2]/div[1]/div//text()').extract()
item = DetailItem() # 实例化
job_desc = ''.join(job_desc).strip()
item['job_desc'] = job_desc
yield item
# items.py
# -*- coding: utf-8 -*- import scrapy
class DetailItem(scrapy.Item):
job_desc = scrapy.Field() class FirstItem(scrapy.Item):
job_title = scrapy.Field()
# pipelines.py
# -*- coding: utf-8 -*-
class BossproPipeline(object):
f1,f2 = None,None
def open_spider(self,spider):
self.f1 = open('a.txt','w',encoding='utf-8')
self.f2 = open('b.txt', 'w', encoding='utf-8') def process_item(self, item, spider):
#item在同一时刻只可以接收到某一个指定item对象
if item.__class__.__name__ == 'FirstItem':
job_title = item['job_title']
self.f1.write(job_title+'\n')
else:
job_desc = item['job_desc']
self.f2.write(job_desc+'\n')
return item
# 分布式爬虫实例 -- 东莞阳光网 http://wz.sun0769.com/index.php/question/questionType?type=4&page=
- 分布式爬虫
- 概念:使用多台机器组成一个分布式的机群,在机群中运行同一组程序,进行联合数据的爬取。
- 原生的scrapy是不可以实现分布式:
- 原生的scrapy中的调度器不可以被共享
- 原生的scrapy的管道不可以被共享
- 如何实现分布式? 就必须使用scrapy-redis(模块)
- 可以给原生的scrapy提供可以被共享的管道和调度器
- pip install scrapy_redis
- 搭建流程:
- 创建工程
- 爬虫文件 crawlSpider
- 修改爬虫文件:
- 导包:from scrapy_redis.spiders import RedisCrawlSpider
- 将当前爬虫类的父类进行修改 RedisCrawlSpider
- allowed_domains,start_url删除,添加一个新属性redis_key(调度器队列的名称)
- 数据解析,将解析的数据封装到item中然后向管道提交
- 配置文件的编写:
- 指定管道:
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
- 指定具体的redis:
REDIS_HOST = 'redis服务的ip地址'
REDIS_PORT = 6379
REDIS_ENCODING = ‘utf-8’
REDIS_PARAMS = {‘password’:’123456’}
- 开启redis服务(携带redis的配置文件:redis-server ./redis.windows.conf),和客户端redis-cli:
- 对redis的配置文件进行适当的配置:
- #bind 127.0.0.1 # 注释host的绑定
- protected-mode no # 关闭保护模式
- 开启
- 启动程序:scrapy runspider xxx.py
- 向调度器队列中扔入一个起始的url(redis的客户端):lpush redis_key的值 www.xxx.com(起始url)
tips: 机群分布式实测试现的时候,可以修改线程数小点(比如3-5个).
flushdb 命令用于清空当前数据库中的所有 key
# 爬虫文件
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_redis.spiders import RedisCrawlSpider
from fbsPro.items import FbsproItem
class TestSpider(RedisCrawlSpider): #修改这个
name = 'test'
# allowed_domains = ['www.xxx.com']
# start_urls = ['http://www.xxx.com/']
#调度器队列的名称
redis_key = 'dongguan'
rules = (
Rule(LinkExtractor(allow=r'type=4&page=\d+'), callback='parse_item', follow=True),
) def parse_item(self, response):
a_list = response.xpath('//a[@class="news14"]')
for a in a_list:
item = FbsproItem() #实例化
item['title']= a.xpath('./text()').extract_first()
yield item
# items.py
# -*- coding: utf-8 -*-
import scrapy
class FbsproItem(scrapy.Item):
title = scrapy.Field()
# settings.py 里面 ITEM_PIPELINES = {
# 'fbsPro.pipelines.FbsproPipeline': 300,
'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 # 增量式的实现,爬过的数据就不再爬取了 REDIS_HOST = '192.168.11.154'
REDIS_PORT = 6379
# 关于Redis存储时候的一些注意事项
服务端启动 redis-server ./redis.windows.conf
客户端 redis-cli -h '192.168.11.161' -p 密码 (这样可以连接别人的远程redis server端)
crawlSpider全站爬取 分布式的更多相关文章
- scrapy_全站爬取
如何查询scrapy有哪些模版? scrapy genspider –list 如何创建crawl模版? scrapy genspider -t crawl 域名 scrapy genspider - ...
- 爬虫---scrapy全站爬取
全站爬取1 基于管道的持久化存储 数据解析(爬虫类) 将解析的数据封装到item类型的对象中(爬虫类) 将item提交给管道, yield item(爬虫类) 在管道类的process_item中接手 ...
- 基于selenium+phantomJS的动态网站全站爬取
由于需要在公司的内网进行神经网络建模试验(https://www.cnblogs.com/NosenLiu/articles/9463886.html),为了更方便的在内网环境下快速的查阅资料,构建深 ...
- scrapy框架用CrawlSpider类爬取电影天堂.
本文使用CrawlSpider方法爬取电影天堂网站内国内电影分类下的所有电影的名称和下载地址 CrawlSpider其实就是Spider的一个子类. CrawlSpider功能更加强大(链接提取器,规 ...
- scrapy架构与目录介绍、scrapy解析数据、配置相关、全站爬取cnblogs数据、存储数据、爬虫中间件、加代理、加header、集成selenium
今日内容概要 scrapy架构和目录介绍 scrapy解析数据 setting中相关配置 全站爬取cnblgos文章 存储数据 爬虫中间件和下载中间件 加代理,加header,集成selenium 内 ...
- python爬虫---CrawlSpider实现的全站数据的爬取,分布式,增量式,所有的反爬机制
CrawlSpider实现的全站数据的爬取 新建一个工程 cd 工程 创建爬虫文件:scrapy genspider -t crawl spiderName www.xxx.com 连接提取器Link ...
- scrapy全站爬取拉勾网及CrawSpider介绍
一.指定模板创建爬虫文件 命令 创建成功后的模板,把http改为https 二.CrawSpider源码介绍 1.官网介绍: 这是用于抓取常规网站的最常用的蜘蛛,因为它通过定义一组规则为跟踪链接提供了 ...
- crawlspider抽屉爬取实例+分布
创建项目 scrapy startproject choutiPro 创建爬虫文件 scrapy genspider -t crawl chouti www.xxx.com 进入pycharm 培训 ...
- 简书全站爬取 mysql异步保存
# 简书网 # 数据保存在mysql中; 将selenium+chromedriver集成到scrapy; 整个网站数据爬取 # 抓取ajax数据 #爬虫文件 # -*- coding: utf-8 ...
随机推荐
- codeforces 1282 E. The Cake Is a Lie (dfs+构造)
链接:https://codeforces.com/contest/1282/problem/E 题意:给的是一张平面图,是一个n边形,每次可以切一刀,切出一个三角形,最终切成n-2个三角形.题目给出 ...
- 13-Java-JSP知识梳理
一.JSP了解 JSP(java server pages,服务器页面),可理解为HTML+ Java = = JSP,它可生成动态的HTML(拼标签).是以.jsp为后缀的文件, 内容是以标签为主体 ...
- Java+Selenium+Testng自动化测试学习(四)— 报告
自动化测试报告,在测试用例完成之后系统自动生成HTML报告 使用testng中的报告模板生成报告, 1.在TestSuit.xml文件中配置报告监听 2.运行xml文件 3.自动生成一个test-ou ...
- AcWing 282. 石子合并
#include <iostream> #include <algorithm> using namespace std; ; int n; int s[N];//前缀和 in ...
- PHP 可选参数
function chooseable($a,$b,$d,$c="我是可选参数c"){ //注意:可选参数一定要是在必选参数后面(有默认值就是可选参数):PHP中参数一定要变量符号 ...
- Golang利用第三方包获取本机cpu使用率以及内存使用情况
第三方包下载 $ github.com/shirou/gopsutil 获取内存方面的信息 package main import ( "fmt" "github.com ...
- docker 环境部署
docker 查看所有容器 docker ps -a docker 查看所有running 容器: docker ps docker 停止全部容器: docker stop $(docker ps ...
- 淘宝 Api 查询手机号
https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13834782535 淘宝 Api 查询手机号
- linux centos7分区
哈喽! 我今天来分享一下Linux的分区,本次我使用的是LinuxCentos7版本为例,使用虚拟机,命令是fdisk Linux分区有4个主分区及扩展分区,逻辑分区. 首先给虚拟机添加8G硬盘(硬盘 ...
- 主席树+二分 p4602
题意:给出每一种果汁的美味度,价格,升数: m个询问,每个询问给出最高上限的钱g,以及给出最少的w 意思是,最多用g的钱去买最少l的果汁,问能得到的最大美味度: 美味度是取所有果汁中美味度的最小值: ...