Python爬虫Scrapy轮子工具
Scrapy
万字长文,建议使用目录点击查阅,有助于高效开发。建议点赞收藏
文章目录
- Scrapy
- 概念
- 模块作用
- 开发步骤
- 爬虫文件 spiders.py
- 代码流程
- 提取数据
- scrapy.Request发送post请求
- 发送post请求
- response响应
- Cookie
- 参数解释
- meta参数的使用
- 管道 piplines.py
- pipeline中常用的方法:
- 开启管道
- 多个管道的开启作用
- MongoDB 持久化
- Json 持久化
- MySql 持久化
- Csv持久化
- 中间件 middleware.py
- 中间件的分类
- Scrapy中间的作用(预处理Request和Response对象)
- Downloader Middlewares默认的方法:
- fake_useragent
- ip_proxy
- 方法一【免费代理】:
- 方法二【收费代理】:
- Scrapy-redis
- Scrapy-bloomfilter布隆过滤器
- 设置 settings.py
- 常用变量
- 启动运行
- 方法一【运行单个爬虫文件】:
- 方法二【 串行 运行完第一个才会运行下一个】:
- 方法三【在进程里面跑多个爬虫】:
概念
scrapy框架的运行流程以及数据传递过程:
- 爬虫中起始的url构造成request对象–>爬虫中间件–>引擎–>调度器
- 调度器把request–>引擎–>下载中间件—>下载器
- 下载器发送请求,获取response响应---->下载中间件---->引擎—>爬虫中间件—>爬虫
- 爬虫提取url地址,组装成request对象---->爬虫中间件—>引擎—>调度器,重复步骤2
- 爬虫提取数据—>引擎—>管道处理和保存数据
模块作用
引擎(engine):负责数据和信号在不腰痛模块间的传递
调度器(scheduler):实现一个队列,存放引擎发过来的request请求对象
下载器(downloader):发送引擎发过来的request请求,获取响应,并将响应交给引擎
爬虫(spider):处理引擎发过来的response,提取数据,提取url,并交给引擎
管道(pipeline):处理引擎传递过来的数据,比如存储
下载中间件(downloader middleware):可以自定义的下载扩展,比如设置代理ip
爬虫中间件(spider middleware):可以自定义request请求和进行response过滤,与下载中间件作用重复
开发步骤
创建项目:
scrapy startproject mySpider
scrapy startproject <项目名字>生成一个爬虫【在项目目录下执行】:
scrapy genspider lianjia lianjia.com
scrapy genspider <爬虫名字> <允许爬取的域名>爬虫名字: 作为爬虫运行时的参数
允许爬取的域名: 为对于爬虫设置的爬取范围,设置之后用于过滤要爬取的url,如果爬取的url与允许的域不通则被过滤掉。
提取数据:
修改start_urls
检查修改allowed_domains
编写解析方法
根据网站结构在spider中实现数据采集相关内容保存数据:
在pipelines.py文件中定义对数据处理的管道
在settings.py文件中注册启用管道
启动项目
爬虫文件 spiders.py
代码流程
- 完善并使用Item数据类:
- 在items.py中完善要爬取的字段
- 在爬虫文件中先导入Item
- 实力化Item对象后,像字典一样直接使用
- 构造Request对象,并发送请求:
- 导入scrapy.Request类
- 在解析函数中提取url
- yield scrapy.Request(url, callback=self.parse_detail, meta={})
- 利用meta参数在不同的解析函数中传递数据:
- 通过前一个解析函数 yield scrapy.Request(url, callback=self.xxx, meta={}) 来传递meta
- 在self.xxx函数中 response.meta.get(‘key’, ‘’) 或 response.meta[‘key’] 的方式取出传递的数据
提取数据
解析并获取scrapy爬虫中的数据:
1. response.xpath方法的返回结果是一个类似list的类型,其中包含的是selector对象,操作和列表一样,但是有一些额外的方法
2. extract() 返回一个包含有字符串的列表,配合[0]使用
3. extract_first() 返回列表中的第一个字符串,列表为空没有返回None
4. get() 提取列表中第1个文本内容(等同于extract_first())
scrapy.Request发送post请求
我们知道可以通过scrapy.Request()指定method、body参数来发送post请求;但是通常使用scrapy.FormRequest()来发送post请求
发送post请求
注意:scrapy.FormRequest()能够发送表单和ajax请求,参考阅读 https://www.jb51.net/article/146769.htm
response响应
response.url:当前响应的url地址
1. response.request.url:当前响应对应的请求的url地址
2. response.headers:响应头
3. response.requests.headers:当前响应的请求头
4. response.body:响应体,也就是html代码,byte类型
5. response.status:响应状态码
Cookie
1.在settings.py中通过设置COOKIES_DEBUG=TRUE 能够在终端看到cookie的传递传递过程
2.如果start_url地址中的url是需要登录后才能访问的url地址,则需要重写3.start_request方法并在其中手动添加上cookie
4.如果重新start_requests()方法,则需要去掉start_urls变量
参数解释
- 中括号里的参数为可选参数
- callback:表示当前的url的响应交给哪个函数去处理
- meta:实现数据在不同的解析函数中传递,meta默认带有部分数据,比如下载延迟,请求深度等
- dont_filter:默认为False,会过滤请求的url地址,即请求过的url地址不会继续被请求,对需要重复请求的url地址可以把它设置为Ture,比如贴吧的翻页请求,页面的数据总是在变化;start_urls中的地址会被反复请求,否则程序不会启动
- method:指定POST或GET请求
- headers:接收一个字典,其中不包括cookies
- cookies:接收一个字典,专门放置cookies
- body:接收json字符串,为POST的数据,发送payload_post请求时使用(在下一章节中会介绍post请求)
- 注意:解析函数中的yield能够传递的对象只能是:BaseItem, Request, dict, None
meta参数的使用
- meta的作用:meta可以实现数据在不同的解析函数中的传递
在爬虫文件的parse方法中,提取详情页增加之前callback指定的parse_detail函数:
def parse(self,response):...yield scrapy.Request(detail_url, callback=self.parse_detail,meta={"item":item})
...def parse_detail(self,response):#获取之前传入的itemitem = resposne.meta["item"]
注意
1. meta参数是一个字典
2. meta字典中有一个固定的键proxy
,表示代理ip,关于代理ip的使用我们将在scrapy的下载中间件
管道 piplines.py
管道的基本使用:
1. 完善pipelines.py中的process_item函数
2. 在settings.py中设置开启pipeline
3. pipeline在setting中键表示位置(即pipeline在项目中的位置可以自定义),值表示距离引擎的远近,越近数据会越先经过:权重值小的优先执行
4. 1. 有多个pipeline的时候,process_item的方法必须return item,否则后一个pipeline取到的数据为None值
5. pipeline中process_item的方法必须有,否则item没有办法接受和处理
6. process_item方法接受item和spider,其中spider表示当前传递item过来的spider
pipeline中常用的方法:
- process_item(self,item,spider):
- 管道类中必须有的函数
- 实现对item数据的处理
- 必须return item
- open_spider(self, spider): 在爬虫开启的时候仅执行一次
- close_spider(self, spider): 在爬虫关闭的时候仅执行一次
开启管道
在settings.py设置开启pipeline
ITEM_PIPELINES = {'myspider.pipelines.ItcastFilePipeline': 400, # 400表示权重'myspider.pipelines.ItcastMongoPipeline': 500, # 权重值越小,越优先执行!
}
多个管道的开启作用
1. 不同的pipeline可以处理不同爬虫的数据,通过spider.name属性来区分
2. 不同的pipeline能够对一个或多个爬虫进行不同的数据处理的操作,比如一个进行数据清洗,一个进行数据的保存
3. 同一个管道类也可以处理不同爬虫的数据,通过spider.name属性来区分
MongoDB 持久化
# 【1】settings.py中添加
ITEM_PIPELINES = {# 添加MongoDB管道'Tencent.pipelines.TencentMongoPipeline': 400,
}
MONGO_HOST = '127.0.0.1'
MONGO_PORT = 27017
MONGO_DB = 'tencentdb'
MONGO_SET = 'tencentset'# 【2】pipelines.py中新建MongoDB管道类
from .settings import *
import pymongoclass TencentMongoPipeline:def open_spider(self, spider):self.conn = pymongo.MongoClient(MONGO_HOST, MONGO_PORT)self.db = self.conn[MONGO_DB]self.myset = self.db[MONGO_SET]def process_item(self, item, spider):self.myset.insert_one(dict(item))
Json 持久化
import jsonclass WangyiPipeline(object):def open_spider(self, spider):if spider.name == 'job':self.file = open('wangyi.json', 'w')def process_item(self, item, spider):if spider.name == 'job':item = dict(item)str_data = json.dumps(item, ensure_ascii=False) + ',\n'self.file.write(str_data)return itemdef close_spider(self, spider):if spider.name == 'job':self.file.close()
MySql 持久化
1)MySQL建表
create database tencentdb charset utf8;
use tencentdb;
create table tencenttab(
job_name varchar(200),
job_type varchar(200),
job_duty varchar(2000),
job_require varchar(2000),
job_add varchar(100),
job_time varchar(100)
)charset=utf8;
2)MySql数据持久化
# 【1】settings.py添加
ITEM_PIPELINES = {# 在原来基础上添加MySQL的管道'Tencent.pipelines.TencentMysqlPipeline': 200,
}
MYSQL_HOST = '127.0.0.1'
MYSQL_USER = 'root'
MYSQL_PWD = '123456'
MYSQL_DB = 'tencentdb'
CHARSET = 'utf8'# 【2】pipelines.py新建MySQL管道类
from .settings import *
import pymysqlclass TencentMysqlPipeline:def open_spider(self, spider):self.db = pymysql.connect(MYSQL_HOST, MYSQL_USER, MYSQL_PWD, MYSQL_DB, charset=CHARSET)self.cur = self.db.cursor()self.ins = 'insert into tencenttab values(%s,%s,%s,%s,%s,%s)'def process_item(self, item, spider):li = [item['job_name'],item['job_type'],item['job_duty'],item['job_require'],item['job_add'],item['job_time'],]self.cur.execute(self.ins, li)self.db.commit()return itemdef close_spider(self, item, spider):self.cur.close()self.db.close()
- 进阶:mysql连接池
Csv持久化
- piplines.py
import csvclass LianjiaspiderPipeline(object):def open_spider(self, spider):if spider.name == "home":self.file = open('lianjia.csv', 'w', encoding="utf-8")self.f_csv = csv.writer(self.file)headers = ['地址', '总价', '单价', '户型', '面积', "朝向", "楼层", "装修程度", "详情页url"]self.f_csv.writerow(headers)def process_item(self, item, spider):if spider.name == "home":data = [item["address"], item["price"], item["unit_price"], item["door_model"], item["area"],item["direction"], item["floor"], item["decorate"], item["info_url"]]self.f_csv.writerow(data)print(data)return itemdef close_spider(self, spider):if spider.name == "home":self.file.close()
- settings.py
# 管道
ITEM_PIPELINES = {'LianJiaSpider.pipelines.LianjiaspiderPipeline': 300,
}
中间件 middleware.py
中间件的分类
1.下载器中间件
2.爬虫中间件
Scrapy中间的作用(预处理Request和Response对象)
1. 对header以及cookie进行更换和处理
2. 使用代理ip等
3. 对请求进行定制化操作,但在scrapy默认的情况下 两种中间件都在middlewares.py一个文件中爬虫中间件使用方法和下载中间件相同,且功能重复,通常使用下载中间件
Downloader Middlewares默认的方法:
process_request(self, request, spider):
- 当每个request通过下载中间件时,该方法被调用。
2. 返回None值:没有return也是返回None,该request对象传递给下载器,或通过引擎传递给其他权重低的process_request方法
3. 返回Response对象:不再请求,把response返回给引擎
4. 返回Request对象:把request对象通过引擎交给调度器,此时将不通过其他权重低的process_request方法
- 当每个request通过下载中间件时,该方法被调用。
process_response(self, request, response, spider):
- 当下载器完成http请求,传递响应给引擎的时候调用
2. 返回Resposne:通过引擎交给爬虫处理或交给权重更低的其他下载中间件的process_response方法
3. 返回Request对象:通过引擎交给调取器继续请求,此时将不通过其他权重低的process_request方法
- 当下载器完成http请求,传递响应给引擎的时候调用
在settings.py中配置开启中间件,权重值越小越优先执行
fake_useragent
- middlewares.py
from fake_useragent import UserAgent
class RandomUserAgentMiddleware(object):def process_request(self, request, spider):ua = UserAgent()request.headers['User-Agent'] = ua.random
- settings.py
DOWNLOADER_MIDDLEWARES = {'xxx项目名.middlewares.RandomUserAgentMiddleware': 300,
}
注意:UserAgent中间件设置为None,这样就不会启用,否则默认系统的这个中间会被启用。
ip_proxy
方法一【免费代理】:
- settings.py
DOWNLOADER_MIDDLEWARES = {'项目名.middlewares.RandomProxy': 543,
}
PROXY_LIST =[{"ip_port": "123.207.53.84:16816", "user_passwd": "morganna_mode_g:ggc22qxp"},# {"ip_port": "122.234.206.43:9000"},
]
- middlewares.py
from 项目名.settings import PROXY_LISTclass RandomProxy(object):def process_request(self, request, spider):proxy = random.choice(PROXY_LIST)print(proxy)if 'user_passwd' in proxy:# 对账号密码进行编码,python3中base64编码的数据必须是bytes类型,所以需要encodeb64_up = base64.b64encode(proxy['user_passwd'].encode())# 设置认证request.headers['Proxy-Authorization'] = 'Basic ' + b64_up.decode()# 设置代理request.meta['proxy'] = proxy['ip_port']else:# 设置代理request.meta['proxy'] = proxy['ip_port']
方法二【收费代理】:
收费代理ip:
# 人民币玩家的代码(使用abuyun提供的代理ip)
import base64# 代理隧道验证信息 这个是在那个网站上申请的
proxyServer = 'http://proxy.abuyun.com:9010' # 收费的代理ip服务器地址,这里是abuyun
proxyUser = 用户名
proxyPass = 密码
proxyAuth = "Basic " + base64.b64encode(proxyUser + ":" + proxyPass)class ProxyMiddleware(object):def process_request(self, request, spider):# 设置代理request.meta["proxy"] = proxyServer# 设置认证request.headers["Proxy-Authorization"] = proxyAuth
- 检测代理ip是否可用
在使用了代理ip的情况下可以在下载中间件的process_response()方法中处理代理ip的使用情况,如果该代理ip不能使用可以替换其他代理ip
class ProxyMiddleware(object):......def process_response(self, request, response, spider):if response.status != '200':request.dont_filter = True # 重新发送的请求对象能够再次进入队列return requst
- settings.py
DOWNLOADER_MIDDLEWARES = {
'myspider.middlewares.ProxyMiddleware': 543,
}
Scrapy-redis
- settings.py 文件配置[注意:scrapy-redis 与 bloomfilter 二者只能选其一使用]
# scrapy-redis分布式配置 pip install scrapy-redis
# 重新指定调度器: 启用Redis调度存储请求队列!!!
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 重新指定去重机制: 确保所有的爬虫通过Redis去重!!!
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"# redis配置
REDIS_HOST = '127.0.0.1' # ip
REDIS_PORT = 6379 # 端口
# REDIS_PARAMS = {
# 'password': '', # 密码
# }
Scrapy-bloomfilter布隆过滤器
- settings.py文件配置
# 布隆过滤器配置 pip install scrapy-redis-bloomfilter
# 重新指定调度器
SCHEDULER = "scrapy_redis_bloomfilter.scheduler.Scheduler"
# 重新指定去重机制
DUPEFILTER_CLASS = "scrapy_redis_bloomfilter.dupefilter.RFPDupeFilter"
# 使用哈希函数的数量,默认为6
BLOOMFILTER_HASH_NUMBER = 6
# 使用Bloomfilter的Redis内存,30表示2^30 = 128MB,默认为30
BLOOMFILTER_BIT = 30
设置 settings.py
常用变量
设置数据导出编码(主要针对于json文件)FEED_EXPORT_ENCODING = 'utf-8'
设置User-AgentUSER_AGENT = ''
设置最大并发数(默认为16)CONCURRENT_REQUESTS = 32
下载延迟时间(每隔多长时间请求一个网页)DOWNLOAD_DELAY = 0.5
请求头DEFAULT_REQUEST_HEADERS = {'Cookie' : 'xxx'}
添加项目管道ITEM_PIPELINES = {'目录名.pipelines.类名' : 优先级}COOKIES_ENABLED = False
启动运行
方法一【运行单个爬虫文件】:
在根目录下创建start.py
from scrapy import cmdlinecmdline.execute("scrapy crawl hot".split()) # cmdline.execute("scrapy crawl hot -o hot.csv".split()) # 导出csv# cmdline.execute("scrapy crawl hot -o hot.json".split()) # 导出json# 注意: settings.py中设置导出编码 - 主要针对json文件FEED_EXPORT_ENCODING = 'utf-8'
Excel打开csv时出现乱码
- 解决办法:用记事本打开CSV,文件菜单中另存为UTF-8保存
方法二【 串行 运行完第一个才会运行下一个】:
在根目录下创建main.py
from scrapy.cmdline import executeexecute("scrapy crawl 爬虫文件名1".split()) execute("scrapy crawl 爬虫文件名2".split())
方法三【在进程里面跑多个爬虫】:
在根目录下创建main.py
from scrapy.crawler import CrawlerProcess from scrapy.utils.project import get_project_settingssettings = get_project_settings()crawler = CrawlerProcess(settings)crawler.crawl('爬虫文件名1') crawler.crawl('爬虫文件名2')crawler.start() crawler.start()
Python爬虫Scrapy轮子工具相关推荐
- Python爬虫Request轮子工具
SuperSpider 万字长文,建议使用目录点击查阅,有助于高效开发.建议点赞收藏 文章目录 SuperSpider Request抓取思路步骤 多级页面数据抓取思路 UserAgent反爬处理 C ...
- Python爬虫 - scrapy - 爬取妹子图 Lv1
0. 前言 这是一个利用python scrapy框架爬取网站图片的实例,本人也是在学习当中,在这做个记录,也希望能帮到需要的人.爬取妹子图的实例打算分成三部分来写,尝试完善实用性. 系统环境 Sys ...
- Python爬虫——Scrapy 的基本使用
文章目录 Python爬虫--Scrapy 的基本使用 1.创建 Scrapy 爬虫项目 2.Scrapy-创建爬虫文件 3.Scrapy-运行爬虫文件 Python爬虫--Scrapy 的基本使用 ...
- Python爬虫 scrapy框架爬取某招聘网存入mongodb解析
这篇文章主要介绍了Python爬虫 scrapy框架爬取某招聘网存入mongodb解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 创建项目 sc ...
- python爬虫--Scrapy框架--Scrapy+selenium实现动态爬取
python爬虫–Scrapy框架–Scrapy+selenium实现动态爬取 前言 本文基于数据分析竞赛爬虫阶段,对使用scrapy + selenium进行政策文本爬虫进行记录.用于个人爬虫学习记 ...
- Python爬虫—Scrapy框架—Win10下载安装
Python爬虫-Scrapy框架-Win10下载安装 1. 下载wheel 2.下载twisted 3. 下载pywin32 4. 下载安装Scrapy 5. 创建一个scrapy项目 6. fir ...
- Python爬虫——Scrapy 简介和安装
文章目录 Python爬虫--Scrapy 简介和安装 1.Scrapy 简介 2.Scrapy 下载安装 Python爬虫--Scrapy 简介和安装 1.Scrapy 简介 Scrapy 简介 S ...
- Python爬虫抓包工具使用
Python爬虫抓包工具使用 一. 常用的工具 python pycharm 浏览器 chrome 火狐 fiddler 2 fiddler的使用 二. 操作界面 三.界面含义 1. 请求 (Requ ...
- Python爬虫-Scrapy框架(四)- 内置爬虫文件 - 4.2 初探Crawl Spider
Python爬虫-Scrapy框架(四)- 内置爬虫文件 - 4.2 初探Crawl Spider 写在前面 初探Crawl Spider 创建Crawl Spider项目 对比Basic与Crawl ...
最新文章
- python reduce()函数
- access sql 取余_计算机二级ACCESS模拟题库2016最新
- 斯坦福大学2014机器学习教程中文笔记目录
- TEEC_AllocateSharedMemory()和 TEEC_RegisterSharedMemory()的总结
- java 无法继承抽象类_java抽象类可以被继承吗?
- 腾讯视频已上线超前点播选集解锁
- 能够生成动态图片的R模块:rCharts
- 浅谈栈和队列的有关面试题
- 高中计算机教学设计案例分析,高一年级信息技术教学设计(案例)
- 用计算机怎么按四分之三次方等于多少,八十一分之十六的负四分之三次方怎么算,要具体过程,答案是多少?...
- B站html5直播黑屏,b站H5播放器改版后失效 · Issue #777 · the1812/Bilibili-Evolved · GitHub...
- wincc 服务器授权型号,WINCC 授权详解
- 计算机怎么显示正确,电脑显示器怎么正确设置
- Java开发 - Redis初体验
- 如何制定 - 测试计划和策略 (详细讲解)
- 使用opencv截取旋转框目标
- strcmp函数的分析及实现
- 【Python_PyQtGraph 学习笔记(五)】基于PyQtGraph和GraphicsLayoutWidget动态绘图并实现窗口模式,且保留全部绘图信息
- SpringBoot+Vue+Element-UI实现人事管理系统
- 计算机思维 第7章
热门文章
- pytorch学习笔记——Sequential的使用和Flatten和flatten的区别
- Linux课程设计石头剪刀布,课程设计-石头剪刀布程序.doc
- 习题2.7 编写程序,输出0到360中所有度数为5°倍数的角度的正弦值和余弦值
- iOS HAMC(哈希)256带密钥的加密方法
- 我逼走创业合伙人,白干七年净身出户,我是跪着前行的CEO
- oracle clear buffer,Out 对象的 clearBuffer() 方法用来清除缓冲区里的数据,但并不把数据写到客户端。...
- 【Python打卡2019】20190417之计算BMR
- HTML5期末大作业:关于家乡景点介绍主题——上海介绍(5页) HTML+CSS+JavaScript 大二实训HTML作业...
- 查询oracle表空间是否满了,oracle表空间满了,导致数据不能写入数据库
- [小游戏资源] 微信小游戏开发资源目录