带有验证码的模拟登陆-12306

我们在登录界面,输入用户名和密码之后,点击提交按钮, 浏览器会向服务器发送一个post请求, 该请求的表单数据中就包含我们输入的用户名密码等信息, 有一些做了加密的网站还可能包含一些类似 _token,的数据信息,对于这样的网站我们只需要构造表单数据, 然后向服务器发送post请求就可以实现模拟登陆了, 但是有一些做了验证码的网站, 我们就不能靠这种方法登陆了, 我们要借助selenium, 打码平台, 来帮助我们识别验证码,进行模拟登陆, 如12306网站的登录

登录的难点在于验证码的识别:

  识别验证码的步骤:

    1. 用selenium访问登录界面,待页面加载完成后, 截取整张页面
    2. 用selenium查找标签的方法, 找到验证码图片标签, 这个标签有两个属性, location(图片左上角坐标), size(图片长和宽), 构造一个rangle()
    3. 用PIL的Image.open() 打开图片, 调用crop(rangle)方法, 将验证码图片从整张图片上截取下来,
    4. 将验证码图片发送给超级鹰处理,返回的就是需要点击的坐标,(相对坐标,相对于验证码图片左上角的坐标), 将返回结果修改成数组结构
    5. 用selenium的动作链, 实现点击操作
    6. 用selenium 输入用户名和密码, 点击登录

  

import time
from PIL import Image
from selenium import webdriver
from chaojiying import Chaojiying_Client
from selenium.webdriver import ActionChains

def getCode(imgpath, imgType):
    chaojiying = Chaojiying_Client('xxxxxxxx', 'xxx', 'xxxxxxx')
    im = open(imgpath, 'rb').read()
    return chaojiying.PostPic(im, imgType)['pic_str']

bro = webdriver.Chrome()
url = 'https://kyfw.12306.cn/otn/login/init'
bro.get(url)
time.sleep(5)


#截取验证码图片

#截取整张页面的图片
bro.save_screenshot('main.png')

#确定截取的范围
#找到验证码图片
img_ele = bro.find_element_by_xpath('//img[@class="touclick-image"]')
#location表示的是验证码图片的左上角的坐标
location = img_ele.location #{'x': 256, 'y': 274}
# print('location:', location)
#size返回的是图片的长和宽
size = img_ele.size   #{'height': 190, 'width': 293}
# print('size:',size)

#rangle就是制定好的截取范围
rangle = (int(location['x']), int(location['y']), int(location['x'])+int(size['width']), int(location['y'])+int(size['height']))
print(rangle)

#根据制定好的范围进行截图
i = Image.open('main.png')
#code_img_name 验证码图片的名称
code_img_name = 'code.png'
frame = i.crop(rangle)
frame.save(code_img_name)

#记录: code.png就是验证码图片, main.png就是当前登录页面对应的图片
result = getCode('code.png', 9004)
#返回的单组坐标数据 119,140
#返回的多组坐标数据 119,140|177,139|248,84
# 我们想要的数据结构式数组类型 [[119,140], [177,139]]
all_points = []
for i in result.split('|'):
    all_points.append(i.split(','))
print('all_points', all_points)

#基于selenium根据all_points进行定点的点击操作
for point in all_points:
    x = point[0]
    y = point[1]
    ActionChains(bro).move_to_element_with_offset(img_ele,int(x),int(y)).click().perform()
    time.sleep(0.5)

bro.find_element_by_id('username').send_keys('123456787')
time.sleep(2)
bro.find_element_by_id('password').send_keys('asdf1234')
time.sleep(2)
bro.find_element_by_id('loginSub').click()
time.sleep(10)
bro.quit()
原文地址:https://www.cnblogs.com/zhangjian0092/p/11408278.html