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,代理池,模拟登录(打码))相关推荐

  1. Python培训分享:python如何用cookie实现自动模拟登录?

    本期教程Python培训教程为大家带来的是python如何用cookie实现自动模拟登录?据小编的了解,python实现cookie自动登录,目前来说有许多第三方库都可以直接使用,这里以常用的requ ...

  2. python+selenium获取cookie session_Python Selenium模拟登录成功后,使用此cookie、利用requests库进行get时,提示“非法登陆”。...

    一. 步骤概述 a. 模拟登录学校选课系统(使用Selenium库登陆http://xk.suibe.edu.cn/xsxk/login.xk) b. 取得cookie后传入requests的sess ...

  3. Python爬虫——建立IP代理池

    在使用Python爬虫时,经常遇见具有反爬机制的网站.我们可以通过伪装headers来爬取,但是网站还是可以获取你的ip,从而禁掉你的ip来阻止爬取信息. 在request方法中,我们可以通过prox ...

  4. (廿九)Python爬虫:IP代理池的开发

    作为一个爬虫开发者,使用IP代理是必要的一步,我们可以在网上找到免费的高匿IP,比如西刺代理.但是,这些免费的代理大部分都是不好用的,经常会被封禁.所以我们转而考虑购买付费代理.可是,作为一个程序员首 ...

  5. Python爬虫初学(三)—— 模拟登录知乎

    模拟登录知乎 这几天在研究模拟登录, 以知乎 - 与世界分享你的知识.经验和见解为例.实现过程遇到不少疑问,借鉴了知乎xchaoinfo的代码,万分感激! 知乎登录分为邮箱登录和手机登录两种方式,通过 ...

  6. python爬虫:两种方法模拟登录博客园

    第一方法用第三方库(requests):参考http://www.mamicode.com/info-detail-1839685.html 源代码分析 博客园的登录页面非常简单,查看网页源代码,可以 ...

  7. python爬虫 房天下js逆向模拟登录

    js逆向学习后跟着教程第一次实战.目标链接 这次用到的是requests和execjs,execjs主要是用来执行js代码,win系统直接在命令行pip install execjs安装就ok了. 网 ...

  8. python爬虫学习之淘宝模拟登录

    使用教程 下载chrome浏览器 查看chrome浏览器的版本号,对应版本号的chromedriver驱动 pip安装下列包  pip install selenium 登录微博,并通过微博绑定淘宝账 ...

  9. Spring Boot + Java爬虫 + 部署到Linux (三、Java爬虫使用代理,模拟登录,保存cookie)

    很多网站对资源都有一定的限制.如果不登录,不是网站的登录用户(会员)访问的话,一些资源会访问不到.这对我们爬虫是十分不利的.而绝大多数网站都是通过登录之后,向浏览器设置cookie,达到验证的功能. ...

  10. python登录网页账号密码_Python 通过爬虫实现GitHub网页的模拟登录的示例代码

    1. 实例描述 通过爬虫获取网页的信息时,有时需要登录网页后才可以获取网页中的可用数据,例如获取 GitHub 网页中的注册号码时,就需要先登录账号才能在登录后的页面中看到该信息,如下图所示.那么该如 ...

最新文章

  1. 那些下载不了的视频,Python只用1行代码就能直接下载
  2. python写了代码_Python写代码的用法建议
  3. CWDM/DWDM是城域网最好的选择吗?
  4. 小程序分享,获取openid
  5. ABAP development tools实现原理介绍
  6. 32位java jre_JRE8 32位|JRE 8 32位下载 Update 131官方版 - 121下载站
  7. 多路测温系统C51语言,51单片机多路DS18B20温度测量程序
  8. 无线通信数字调制技术
  9. AOP名词解释Advice,Pointcut,Advisor,Joinpoint,Advised是什么?
  10. 基于SSM的美容院管理系统
  11. vue-devtools 具体使用配置详情
  12. “专精特新”背后的京东动力
  13. Windows10系统提速优化
  14. matlab绘制磁场图,基于Matlab的电磁场图示化教学
  15. CV影视TV版3.0.3最新版 家中观影利器
  16. 732. 我的日程安排表 III
  17. Linux服务器运行状况全面监测
  18. XenApp6.0 部署之 二 配置XenApp Server
  19. 数据分析基础知识之数据收集与分析软件
  20. 利用H5Canvas进行前端图片压缩再上传笔记

热门文章

  1. 华为 android 5.0系统下载地址,Emui5.0+Android 华为Nova内测包
  2. 【人脸质量评估】SDD-FIQA基于人脸相似度分布距离的无监督质量评估方法
  3. Ubuntu解决火狐浏览器无法同步书签的问题
  4. 表结构生成html页面,表结构设计器
  5. arcmap 10.2 shp合并
  6. 合同管理系统主要增加了安全性,对于大型企业作用重大
  7. ADS系列之SIPI仿真笔记:ADS多种版本的安装、卸载重装(一)
  8. Android apk 加密方式
  9. apk提取加密素材_高效IO之Dex加密(三)
  10. GitHub 微信公众号爬虫推荐