正在卓尼小乱 发表于 2020-8-7 18:34:37

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

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

#url设置
url='http://192.168.174.134/index.php?r=admin/index/login'
#用户名密码设置
params={
'username':'admin',
'password':'system',
'x':'0'
'y':'0'
}

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

print(cookie)

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



下图是python脚本发出去的数据(红框标注的包):


做的实在没思路了,求解!!{:5_100:}

1q23w31 发表于 2020-8-7 18:44:56

把网页源代码发一下,把图片那部分

正在卓尼小乱 发表于 2020-8-7 18:53:38

1q23w31 发表于 2020-8-7 18:44
把网页源代码发一下,把图片那部分

<!DOCTYPE html>

<head>

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

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

<script language="javascript">

//重载验证码

function fleshVerify()

{

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

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

}

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



</script>

<style type="text/css">

<!--

body{ background-color:#f7f7f7}

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

.STYLE1 {

        color: #333;

        font-size: 12px;

       

}

.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}

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

td{ height:45px;}

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

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

-->

</style>

</head>



<body>

<div class="con">

<div class="for">

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

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

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

            <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>

            <tr><tdalign="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>

            <tr><tdalign="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>

      </table>

      </div>

      

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

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

    </form>

</div>

</div>

</body>

</html>

正在卓尼小乱 发表于 2020-8-7 18:56:08

1q23w31 发表于 2020-8-7 18:44
把网页源代码发一下,把图片那部分

验证码图片是下载成功的,只是怀疑他在下载后刷新了;
因为每一次访问验证码图片地址,那张验证码都会自动刷新,不访问就不变

陈尚涵 发表于 2020-8-7 19:48:53

Wow,我貌似不会{:10_266:}(非洲哭泣)

1q23w31 发表于 2020-8-7 20:27:00

本帖最后由 1q23w31 于 2020-8-7 20:30 编辑

正在卓尼小乱 发表于 2020-8-7 18:56
验证码图片是下载成功的,只是怀疑他在下载后刷新了;
因为每一次访问验证码图片地址,那张验证码都会自 ...

你打开开发者工具,在network里找一下请求验证码的数据包,看他带了哪些参数,自动刷新验证码 ,我还没遇到过

正在卓尼小乱 发表于 2020-8-7 20:48:45


就这几个



1q23w31 发表于 2020-8-7 20:57:19

正在卓尼小乱 发表于 2020-8-7 20:48
就这几个

请求验证码的,不是登陆的

闲鱼君 发表于 2020-8-8 15:04:34

感谢大佬分享有所收获

正在卓尼小乱 发表于 2020-8-8 17:27:45

1q23w31 发表于 2020-8-7 20:57
请求验证码的,不是登陆的


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



陈尚涵 发表于 2020-8-8 17:30:49

鱼币!

1q23w31 发表于 2020-8-8 17:44:48

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

方便远程吗?

正在卓尼小乱 发表于 2020-8-8 17:50:43

1q23w31 发表于 2020-8-8 17:44
方便远程吗?

当然可以,多谢

1q23w31 发表于 2020-8-8 17:51:18

正在卓尼小乱 发表于 2020-8-8 17:50
当然可以,多谢

1260121341

hornwong 发表于 2020-8-8 19:11:13

{:5_95:}

正在卓尼小乱 发表于 2020-8-17 19:11:53

1q23w31 发表于 2020-8-8 17:44
方便远程吗?

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

昨非 发表于 2020-8-17 19:21:28

鱼币
页: [1]
查看完整版本: python爬取验证码自动登录问题(零基础入门学习python54讲)