python爬虫四(cookie,代理池,模拟登录(打码))
requests高级操作:cookie处理,代理操作,验证码识别,模拟登录
cookie:
cookie是存储在客户端的一组键值对,是由服务器端创建。
cookie应用:
免密登录(服务器端将用户id和密码存在cookie中)
案例
爬取该网站中的新闻资讯
https://xueqiu.com/
分析:首页第一屏的数据不是动态加载,直接爬到就拿到实实在在的数据,但是滚轮往下划,会发起ajax请求动态加载,再划就会再次发ajax。这类网站没有页码,前端绑定事件为滚轮滑动,触发回调发起ajax请求动态加载数据到下面,但不是无限,后面划不动,需要手动点击加载更多触发回调)
上图找到了ajax的请求地址,发现每次动态加载请求的url和方式都是一样的,只是携带的查询参数max_id不一样,所以我马上去首页全局搜索这个max_id如20370667,果然,找到了这个装满max_id的json串。
现在我就可以按照headers中的url发起请求拿这个json串。
居然拿不到!(请求方式和请求地址以及请求参数全都正确)上图返回的参数告诉你是因为你没有登录。
根本原因就是请求头中没有带cookie。
手动加:
你肯定马上就会去在请求头加上一个key,value,但是这样不好,cookie写死了,因为cookie是会随时变化的,不是定死的,并且在headers里一大坨cookie数据不好看。
自动加:
实时cookie:调用requests中的Session类来创建Session对象:
session = requests.Session()
session对象作用:
可以像requests一样调用get/post进行请求的发送,在使用session进行请求发送的过程中,如果产生了cookie,则cookie会被自动存储到session对象中。那么在爬虫中使用session对象处理cookie时,session对象至少需要被用几次?
答案是至少两次才算用上了session(带上了cookie),一次是去拿cookie,一次是使用拿到的cookie
session = requests.Session()# 该次请求只是为了拿cookie存储到session对象中
session.get('https://xueqiu.com/',headers=headers)url = 'https://xueqiu.com/v4/statuses/public_timeline_by_category.json?since_id=-1&max_id=20370668&count=15&category=-1'
json_str = session.get(url,headers=headers).json()
print(json_str)
结果:
现在在上图就可以看到包含所有max_id的一堆json串,记住只要模仿的是ajax请求,直接用json()拿数据!!!!!!!因为现在ajax请求后端回来的Reponse中一定肯定只有json数据,非ajax请求Response才是个页面,才用text()或content.decode()来拿。
拿去格式化一下:
然后就根据上图数据结构把所有id塞进一个列表,然后遍历max_id_list ,动态化max_id参数requests发起请求拿数据即可。
# 不用这种用列表生成式也可以
max_id_list = []
for dict in json_str['list']:max_id_list.append(dict[id])
代理操作(代理服务器)
代理服务器就是用来转发请求和响应的,fiddler就是一个典型的代理服务器的抓包工具。
为什么要用代理?
防止服务器知道我们的真实ip,因为爬虫都是在跑循环,很容易被封ip。
代理匿名度:
透明(知道你是用了代理也知道你的真实ip),匿名(知道你使用了代理,但不知道你的真实ip),高匿(不知道你用了代理,更不知道你的真实ip,当然高匿不是为所欲为,追代理商一样能追到你)
代理的类型:
http:只能代理http协议的请求。https:只能代理https协议的请求。socket协议:(基本不用)
如何获取代理服务器?
免费:西祠代理,快代理,goubanjia(这些几乎是不能用的)
付费:芝麻HTTP
http://h.zhimaruanjian.com/
不仅便宜,而且新用户还能免费提取api
案例:高频的requests一个网站,让这个网站封死我们ip,然后使用代理能正常请求到数据。
就爬西祠的所有ip和端口,一是没有ajax动态加载,二是数据量足够(四千多页),三是好爬(每一页的url都是/nn/页码)
ip_list = []
# 我爬的前499页的ip及端口
for i in range(1,500):url = 'https://www.xicidaili.com/nn/{}'.format(i)response = requests.get(url,headers=headers).content.decode()tree = etree.HTML(response)# 排除第一,用[1:],因为第一个是列名称tr_list = tree.xpath('//table[@id="ip_list"]//tr')[1:]for tr in tr_list:# xpath永远返回列表ip = tr.xpath('./td[2]/text()')[0]ip_port = tr.xpath('./td[3]/text()')[0]ip_list.append('{}:{}'.format(ip,ip_port))
print(ip_list)
我们的ip被西祠的服务器封了!
使用代理来接触ip被封的情况:
1、构建一个代理池列表
import random
代理ip池
import random
# 代理ip池
all_ips = [{'https':'58.218.92.91:2538'},{'https':'58.218.92.91:5421'},{'https':'58.218.92.86:4614'}, {'https':'58.218.92.87:4543'},
]
ip_list = []
# 我就只爬一二页了
for i in range(1,3):print('正在爬取第{}页的ip及端口:'.format(i))url = 'https://www.xicidaili.com/nn/{}'.format(i)# random.choice()实现了随机生成指定的数据response = requests.get(url,headers=headers,proxies=random.choice(all_ips)).content.decode()tree = etree.HTML(response)# 排除第一,用[1:],因为第一个是列名称tr_list = tree.xpath('//table[@id="ip_list"]//tr')[1:]for tr in tr_list:# xpath永远返回列表ip = tr.xpath('./td[2]/text()')[0]port = tr.xpath('./td[3]/text()')[0]ip_list.append('{}:{}'.format(ip,port))
print(ip_list)
重新发起请求爬取成功:
问题:
往往在进行大量请求发送的时候,经常会报出这样的一个错误:HTTPConnectionPool Max retires exceeded
原因:
1、都知道cs架构首先要建立TCP连接,TCP为了节省消耗,默认为长连接keep-alive,即连接一次,传输多次,而如果连接迟迟不断开的话,TCP连接池是有限的,满了之后无法塞本次连接进连接池,导致请求无法发送。
解决方法:设置请求头中的Connection的值为close,表示每次请求传输后断开本次连接。
2、ip被服务器封死了。
解决方法:更换请求ip(ip代理池)
3、请求过于频繁。
解决方法:每次requests之间使用sleep时间间隔个一两秒
验证码识别:
线上的打码平台进行验证码识别:云打码,超级鹰(本次使用),打码兔,这三种大码平台用法大同小异。
超级鹰的使用流程:
1、注册,进入用户中心,点击生成一个软件ID
这是超级鹰的打码加个体系,一块钱=1000积分:
2、下载封装好的超级鹰打码的示例代码:在里边封装了一个返回图片验证码结果的函数transform_code_img,调用这个即可打码,记得填上自己的username和password以及softID(要充值积分才能用,一块就行了)
上图中的a.jpg是个验证码图片,测试打码是否可用成功。其他两个平台,也是要封装一下,只不过实现代码不一样。
案例:识别该网站的图片验证码
https://so.gushiwen.org/user/login.aspx
1、解析出本次登陆页面对应的验证码图片地址。
2、发起请求拿到验证码图片到本地,所有网站的验证码图片每访问一次都会变,所我们代码中也必须只请求一次。
3、调用函数打码
具体代码如下:
login_url = 'https://so.gushiwen.org/user/login.aspx'
page_str = requests.get(login_url,headers=headers).content.decode()
tree = etree.HTML(page_str)
# 拿到当前页面的验证码图片的url
img_url = tree.xpath('//div[@class="mainreg2"]/img/@src')[0]
# 拿到图片
img = requests.get('https://so.gushiwen.org'+img_url,headers=headers).content
# 一定要存到本地存
with open('./img.jpg','wb') as f:f.write(img)
# 调函数来识别验证码图片
result = transform_code_img('./img.jpg',1004) # 数字字母混合1-4位类型为1004
print(result)
打码成功,下一步我们就要做模拟登录,那肯定是要携带参数的,至少得带着验证码,用户名及密码去请求登录接口,打开抓包工具,观察点击登录后请求了哪些数据包。很轻松的找到了,就是请求的这个数据包,我们马上带上这些参数进行模拟登录
模拟登录代码如下:
url = 'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx'
data = {'__VIEWSTATE': 'verfNNKZS6lYTcFINM88TFlI9t/NEqNlXgMK2p+XqTLN6bPNDXXOKx04osNq5U6p332iA5EZIRRXEbtNtXaBywUK18Mj7tbSEsGY5BC6qkDqkX87nZX89brCYjY=','__VIEWSTATEGENERATOR': 'C93BE1AE','from': 'http://so.gushiwen.org/user/collect.aspx','email': '18xxx62xx2','pwd': 'axxxxxxlyc','code': result,'denglu': '登录',
}
# result是是前面打出的验证码,这里输出是为了确认正确
print(result)
response = requests.post(url,headers=headers,data=data)
if response.status_code == 200:print('请求成功,但不代表模拟登陆成功,还是需要看页面根真实登录后的页面是否一致')
response_str = requests.post(url,headers=headers,data=data).content.decode()
with open('./gushiwen.html','w',encoding='utf8') as f:f.write(response_str)
然而我请求之后的页面还是个登录页面,没有请求到想要的登陆后的页面。
分析:我请求的url是没错的,但有两个奇怪的请求参数__VIEWSTATE和__VIEWSTATEGENERATOR,这两个的值我在上图的请求体中是写死的,那这两个的值会不会是动态变化的?并且看样子还是加密后的,那我再次登录看这两个值的变化,发现真是变化的。
解决:一般动态变化的请求参数都会被隐藏在首页的源码中。所以老方法在抓包工具中对这个请求参数的名称进行全局搜索,或者在elements中也可以,全局请求包组成的elements,肯定不能搜值撒,要搜键。
果然找到了这两个键。发现他们两个是前端表单隐藏域传值,下一步就是在当前页解析出这个动态值。该页面没有ajax动态加载
__VIEWSTATE = tree.xpath('//div/input[@id="__VIEWSTATE"]/@value')[0]
依然登录失败,应该是cookie导致,用session对象发请求即可,这个其实应该在分析请求体参数之前考虑,因为cookie导致的解决更简单,直接session发请求,那到底是验证码接口还是登录接口给我们塞的cookie呢,我不知道也不需要知道,我两个请求都用session发不就行了吗下面是完整代码:
session = requests.Session() # 创建空对象session
login_url = 'https://so.gushiwen.org/user/login.aspx'
page_str = session.get(login_url,headers=headers).content.decode()
tree = etree.HTML(page_str)
# 拿到当前页面的验证码图片的url
img_url = tree.xpath('//div[@class="mainreg2"]/img/@src')[0]
# 拿到动态参数__VIEWSTATE
__VIEWSTATE = tree.xpath('//div/input[@id="__VIEWSTATE"]/@value')[0]
# 拿到图片
img = session.get('https://so.gushiwen.org'+img_url,headers=headers).content
# 一定要存到本地存
with open('./img.jpg','wb') as f:f.write(img)
# 调函数来识别验证码图片
result = transform_code_img('./img.jpg',1004) # 数字字母混合1-4位类型为1004
print("{}\n{}\n{}".format(result,__VIEWSTATEGENERATOR,__VIEWSTATE))
# 模拟登录
url = 'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx'
data = {# 警示:请求体的数据,键和值都不要用单引号 "__VIEWSTATE": __VIEWSTATE,"__VIEWSTATEGENERATOR":"C93BE1AE","from": "http://so.gushiwen.org/user/collect.aspx?type=s","email": "你的用户名","pwd": "你的密码","code": result,"denglu": "登录",
}
response = requests.post(url,headers=headers,data=data)
if response.status_code == 200:print('请求成功,但不代表模拟登陆成功,还是需要看页面根真实登录后的页面是否一致')
response_str = session.post(url,headers=headers,data=data).content.decode()
with open('./gushiwen.html','w',encoding='utf8') as f:f.write(response_str)
警示:请求体的数据或者以后前后端交互json数据传输,键和值都不要用单引号 ,否则出问题,必须用双引号!!!
梳理:模拟登录涉及到了三种反爬:
一是图片验证码,二是动态化请求体参数,三是cookie
前面学了的反爬还有:
1、robots协议
2、UA请求头
3、ajax来动态生成数据
4、图片懒加载
5、ip代理
6、js加密(最复杂)
7、js混淆
python爬虫四(cookie,代理池,模拟登录(打码))相关推荐
- Python培训分享:python如何用cookie实现自动模拟登录?
本期教程Python培训教程为大家带来的是python如何用cookie实现自动模拟登录?据小编的了解,python实现cookie自动登录,目前来说有许多第三方库都可以直接使用,这里以常用的requ ...
- python+selenium获取cookie session_Python Selenium模拟登录成功后,使用此cookie、利用requests库进行get时,提示“非法登陆”。...
一. 步骤概述 a. 模拟登录学校选课系统(使用Selenium库登陆http://xk.suibe.edu.cn/xsxk/login.xk) b. 取得cookie后传入requests的sess ...
- Python爬虫——建立IP代理池
在使用Python爬虫时,经常遇见具有反爬机制的网站.我们可以通过伪装headers来爬取,但是网站还是可以获取你的ip,从而禁掉你的ip来阻止爬取信息. 在request方法中,我们可以通过prox ...
- (廿九)Python爬虫:IP代理池的开发
作为一个爬虫开发者,使用IP代理是必要的一步,我们可以在网上找到免费的高匿IP,比如西刺代理.但是,这些免费的代理大部分都是不好用的,经常会被封禁.所以我们转而考虑购买付费代理.可是,作为一个程序员首 ...
- Python爬虫初学(三)—— 模拟登录知乎
模拟登录知乎 这几天在研究模拟登录, 以知乎 - 与世界分享你的知识.经验和见解为例.实现过程遇到不少疑问,借鉴了知乎xchaoinfo的代码,万分感激! 知乎登录分为邮箱登录和手机登录两种方式,通过 ...
- python爬虫:两种方法模拟登录博客园
第一方法用第三方库(requests):参考http://www.mamicode.com/info-detail-1839685.html 源代码分析 博客园的登录页面非常简单,查看网页源代码,可以 ...
- python爬虫 房天下js逆向模拟登录
js逆向学习后跟着教程第一次实战.目标链接 这次用到的是requests和execjs,execjs主要是用来执行js代码,win系统直接在命令行pip install execjs安装就ok了. 网 ...
- python爬虫学习之淘宝模拟登录
使用教程 下载chrome浏览器 查看chrome浏览器的版本号,对应版本号的chromedriver驱动 pip安装下列包 pip install selenium 登录微博,并通过微博绑定淘宝账 ...
- Spring Boot + Java爬虫 + 部署到Linux (三、Java爬虫使用代理,模拟登录,保存cookie)
很多网站对资源都有一定的限制.如果不登录,不是网站的登录用户(会员)访问的话,一些资源会访问不到.这对我们爬虫是十分不利的.而绝大多数网站都是通过登录之后,向浏览器设置cookie,达到验证的功能. ...
- python登录网页账号密码_Python 通过爬虫实现GitHub网页的模拟登录的示例代码
1. 实例描述 通过爬虫获取网页的信息时,有时需要登录网页后才可以获取网页中的可用数据,例如获取 GitHub 网页中的注册号码时,就需要先登录账号才能在登录后的页面中看到该信息,如下图所示.那么该如 ...
最新文章
- 那些下载不了的视频,Python只用1行代码就能直接下载
- python写了代码_Python写代码的用法建议
- CWDM/DWDM是城域网最好的选择吗?
- 小程序分享,获取openid
- ABAP development tools实现原理介绍
- 32位java jre_JRE8 32位|JRE 8 32位下载 Update 131官方版 - 121下载站
- 多路测温系统C51语言,51单片机多路DS18B20温度测量程序
- 无线通信数字调制技术
- AOP名词解释Advice,Pointcut,Advisor,Joinpoint,Advised是什么?
- 基于SSM的美容院管理系统
- vue-devtools 具体使用配置详情
- “专精特新”背后的京东动力
- Windows10系统提速优化
- matlab绘制磁场图,基于Matlab的电磁场图示化教学
- CV影视TV版3.0.3最新版 家中观影利器
- 732. 我的日程安排表 III
- Linux服务器运行状况全面监测
- XenApp6.0 部署之 二 配置XenApp Server
- 数据分析基础知识之数据收集与分析软件
- 利用H5Canvas进行前端图片压缩再上传笔记
热门文章
- 华为 android 5.0系统下载地址,Emui5.0+Android 华为Nova内测包
- 【人脸质量评估】SDD-FIQA基于人脸相似度分布距离的无监督质量评估方法
- Ubuntu解决火狐浏览器无法同步书签的问题
- 表结构生成html页面,表结构设计器
- arcmap 10.2 shp合并
- 合同管理系统主要增加了安全性,对于大型企业作用重大
- ADS系列之SIPI仿真笔记:ADS多种版本的安装、卸载重装(一)
- Android apk 加密方式
- apk提取加密素材_高效IO之Dex加密(三)
- GitHub 微信公众号爬虫推荐