鱼C论坛

 找回密码
 立即注册
查看: 2262|回复: 16

[已解决]python爬取验证码自动登录问题(零基础入门学习python54讲)

[复制链接]
发表于 2020-8-7 18:34:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
由于小甲鱼课后习题的目标豆瓣更改了验证码功能,我找了一个靶机网站当做目标,练习python自动登录脚本。
先说下代码功能:先通过get方式访问登录页面爬取源代码,然后用re.search()从源代码里获得验证码图片地址,通过urllib.request.urlretrieve()远程下载验证码到本地,通过g.integerbox()显示这张验证码图片并让用户输入验证码值,将验证码值加进提交数据中提交,获取响应
代码如下:
  1. import re
  2. from urllib import request
  3. from http import cookiejar
  4. from urllib import parse
  5. import easygui as g

  6. #url设置
  7. url='http://192.168.174.134/index.php?r=admin/index/login'
  8. #用户名密码设置
  9. params={
  10. 'username':'admin',
  11. 'password':'system',
  12. 'x':'0'
  13. 'y':'0'
  14. }

  15. #声明一个CookieJar对象实例来保存cookie
  16. cookie=cookiejar.CookieJar()
  17. #利用urllib.request库的HTTPCookieProcessor对象来创建cookie处理器,也就CookieHandler
  18. handler=request.HTTPCookieProcessor(cookie)
  19. #通过CookieHandler创建opener
  20. opener=request.build_opener(handler)
  21. #此处的open方法打开网页,‘访问登录页面’
  22. response=opener.open(url)
  23. html=response.read().decode()

  24. print(cookie)

  25. #寻找验证码图片地址
  26. imgurl=re.search('<img src="(.+?)" border="0"  height="25" width="50" style=" cursor:hand;" alt="如果您无法识别验证码,请点图片更换" onClick="fleshVerify\(\)" id="verifyImg"/>',html)
  27. if imgurl:
  28.     addr='http://192.168.174.134'+imgurl.group(1)
  29.     print(cookie)
  30.     #将验证码图片保存至同目录下,Pyhon访问下载imgurl之后,导致验证码刷新,python下载的验证码就变成了旧的验证码(对于我们这个cookie的用户而言)
  31.     res=request.urlretrieve(addr,'v.png')
  32.     params['checkcode']=str(g.integerbox('请输入验证码:','验证码',lowerbound=0,upperbound=9999,image='v.png'))
  33.     print(params)
  34.     #打包数据
  35.     data=parse.urlencode(params).encode('utf-8')
  36. #提交数据
  37.     response=opener.open(url,data)
  38.     reshtml=response.read().decode('utf-8')
  39.     print(reshtml)
  40.    
复制代码
下图是登录需要提交的数据(x和y应该是没影响的,抓包修改成任意值仍然可以正常登录):
用户名,密码,验证码
cookie是第一次访问登录页面时服务端下发的,只要不关闭页面就会一直存在

微信图片编辑_20200807181027.jpg
微信图片_20200807182840.png
下图是python脚本发出去的数据(红框标注的包):
微信图片_20200807181446.png

做的实在没思路了,求解!!

最佳答案
2020-8-8 17:44:48
正在卓尼小乱 发表于 2020-8-8 17:27
这样子的,看起来就是根据sessid改变验证码,我现在怀疑的是python是否在下载验证码图片的时候,将验证 ...

方便远程吗?
微信截图_20200807181334.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-7 18:44:56 | 显示全部楼层

回帖奖励 +3 鱼币

把网页源代码发一下,把图片那部分
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-7 18:53:38 | 显示全部楼层
1q23w31 发表于 2020-8-7 18:44
把网页源代码发一下,把图片那部分
  1. <!DOCTYPE html>

  2. <head>

  3. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  4. <title>企业信息管理系统_用户登录</title>

  5. <script language="javascript">

  6. //重载验证码

  7. function fleshVerify()

  8. {

  9. var timenow = new Date().getTime();

  10. document.getElementById('verifyImg').src= "/index.php?r=admin/index/verify/"+timenow;

  11. }

  12. //提交数据前,对数据进行检查



  13. </script>

  14. <style type="text/css">

  15. <!--

  16. body{ background-color:#f7f7f7}

  17. *{ margin:0; padding:0; font-size:12px;font-family:'微软雅黑'}

  18. .STYLE1 {

  19.         color: #333;

  20.         font-size: 12px;

  21.        

  22. }

  23. .con{background:url(/public/admin/images/login_bg.jpg) center no-repeat; width:489px; height:341px; position:absolute; left:50%; top:50%; margin:-170px 0 0 -244px}

  24. .for{ padding:100px 0 0 100px}

  25. td{ height:45px;}

  26. .intext{height:25px; line-height:25px;border:1px solid #ccc; font-size:12px; color:#333; padding:0 5px}

  27. .code{ float:left; height:25px}

  28. -->

  29. </style>

  30. </head>



  31. <body>

  32. <div class="con">

  33.   <div class="for">

  34.     <form action=""  method="post" >

  35.        <div style="width:200px; float:left">

  36.         <table cellpadding="0" cellspacing="0" width="80%">

  37.             <tr><td width="20%" align="right"><span class="STYLE1">用&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;户:</span></td> <td width="80%"><input type="text" name="username" id="username" class="intext" size="18"></td></tr>

  38.             <tr><td  align="right"><span class="STYLE1">密&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;码:</span></td> <td><input type="password" name="password" id="password" class="intext" size="18"></td></tr>

  39.             <tr><td  align="right"><span class="STYLE1">验&nbsp;证&nbsp;码:</span></td> <td><div class="code"><input type="text" name="checkcode" id="checkcode" class="intext" size="4"></div> <div class="code">&nbsp;<img src="/index.php?r=admin/index/verify" border="0"  height="25" width="50" style=" cursor:hand;" alt="如果您无法识别验证码,请点图片更换" onClick="fleshVerify()" id="verifyImg"/></div></td></tr>

  40.         </table>

  41.         </div>

  42.         

  43.        <div style="float:left; width:83px; padding-top:9px"><input type="image" src="/public/admin/images/dl.gif" width="83" height="75"></div>

  44.        <p style="display:block; clear:both; padding-top:60px; color: #999">YxcmsApp 1.1.9 Copyright @2012-2013</p>

  45.     </form>

  46.   </div>

  47. </div>

  48. </body>

  49. </html>
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-7 18:56:08 | 显示全部楼层
1q23w31 发表于 2020-8-7 18:44
把网页源代码发一下,把图片那部分

验证码图片是下载成功的,只是怀疑他在下载后刷新了;
因为每一次访问验证码图片地址,那张验证码都会自动刷新,不访问就不变
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-7 19:48:53 | 显示全部楼层

回帖奖励 +3 鱼币

Wow,我貌似不会(非洲哭泣)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-7 20:27:00 | 显示全部楼层
本帖最后由 1q23w31 于 2020-8-7 20:30 编辑
正在卓尼小乱 发表于 2020-8-7 18:56
验证码图片是下载成功的,只是怀疑他在下载后刷新了;
因为每一次访问验证码图片地址,那张验证码都会自 ...


你打开开发者工具,在network里找一下请求验证码的数据包,看他带了哪些参数,自动刷新验证码 ,我还没遇到过
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-7 20:48:45 | 显示全部楼层
微信图片_20200807204729.png
就这几个



小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-7 20:57:19 | 显示全部楼层

请求验证码的,不是登陆的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-8 15:04:34 | 显示全部楼层
感谢大佬分享  有所收获  
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-8 17:27:45 | 显示全部楼层
1q23w31 发表于 2020-8-7 20:57
请求验证码的,不是登陆的

微信图片_20200808172447.png
这样子的,看起来就是根据sessid改变验证码,我现在怀疑的是python是否在下载验证码图片的时候,将验证码刷新了
  1. res=request.urlretrieve(addr,'v.png')
复制代码
或者不是上面这句,而是其他某一句,访问页面的时候,刷新了验证码,导致和服务端的匹配不上



小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-8 17:30:49 | 显示全部楼层
鱼币!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-8 17:44:48 | 显示全部楼层    本楼为最佳答案   
正在卓尼小乱 发表于 2020-8-8 17:27
这样子的,看起来就是根据sessid改变验证码,我现在怀疑的是python是否在下载验证码图片的时候,将验证 ...

方便远程吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-8 17:50:43 | 显示全部楼层

当然可以,多谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-8 17:51:18 | 显示全部楼层

1260121341
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-8 19:11:13 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-17 19:11:53 | 显示全部楼层

自己又研究了requests模块之后终于整明白了!!!
问题出在下载验证码那一步,我一开始用的是res=request.urlretrieve(addr,'v.png')
后来又用了urllib.request.urlopen(addr)来下载
但注意这两种方法在访问验证码地址时,都没有附带cookie,因此是服务器又下发了另一个不同的cookie码并将该cookie码对应的图片给了我。
因此,正确的姿势应该是全程使用opener.open()进行操作:  res=opener.open(addr)
因为opener设置了CookieJar的缘故,是可以一直保存cookie的
请注意顶楼我发的最后一张截图,一目了然
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-17 19:21:28 | 显示全部楼层

回帖奖励 +3 鱼币

鱼币
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-25 22:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表