实现自动登陆的话需要正确的点击图片中的验证码,下面为大家介绍如何自动登录铁路12306,12306登录界面如下所示:
我们在实现过程城中可以借用超级鹰帮助我们实验验证码的点击,首先我们将验证码的图片已截图的形式保存下来,然后我们将截图发送给第三方平台,第三方平台会将我们需要的图片的坐标返回给我们,然后我们对其返回的数据进行处理,然后点击相应的坐标就可以实验登录,当然在此过程中我们需要尽量的模仿人的行为习惯,代码如下:
from selenium import webdriver
import time
from PIL import Image
# 使用显示等待直到页面中需要的元素加载完毕
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
path = r'D:\chromedriver\chromedriver.exe'
bro = webdriver.Chrome(executable_path=path)
bro.get("https://kyfw.12306.cn/otn/resources/login.html")
WebDriverWait(driver=bro, timeout=10).until(
EC.presence_of_all_elements_located((By.ID, 'login-hd-account'))
)
bro.find_element_by_class_name('login-hd-account').click()
time.sleep(4)
WebDriverWait(driver=bro, timeout=10).until((By.ID, 'J-loginImg'))
code_image_ele = bro.find_element_by_id("J-loginImg")
time.sleep(2)
# 获取验证码的图片左上角的坐标
location = code_image_ele.location
print("location", location)
# 获取验证码图片的长度和宽度
size = code_image_ele.size
print("size", size)
# 定义一个元组表示的是左上角和右下角的坐标
rangle = (
int(location['x']), int(location['y']), int(location['x']+size['width']), int(location['y'] + size['height'])
)
# 截取浏览器打开的这张页面对应的图像
bro.save_screenshot("aa.png")
i = Image.open("./aa.png")
# 即将被截图下来的验证码图片的名称
code_img_name = 'code.png'
# 根据左上角与右下角的坐标进行指定区域的截取
frame = i.crop(rangle)
frame.save(code_img_name)
from chaojiying import Chaojiying_Client
chaojiying = Chaojiying_Client('username', 'password', 'ID')
im = open('./code.png', 'rb').read()
result =chaojiying.PostPic(im, 9004)['pic_str']
print("**********", result)
all_list = []
if '|' in result:
list_1 = result.split('|')
count_1 = len(list_1)
for i in range(count_1):
xy_list = []
x = int(list_1[i].split(',')[0])
y = int(list_1[i].split(',')[1])
xy_list.append(x)
xy_list.append(y)
all_list.append(xy_list)
else:
x = int(result.split(',')[0])
y = int(result.split(',')[1])
xy_list = []
xy_list.append(x)
xy_list.append(y)
all_list.append(xy_list)
print(all_list)
from selenium.webdriver.common.action_chains import ActionChains
action = ActionChains(bro)
for l in all_list:
x = l[0]
y = l[1]
# 切换参照系,返回的坐标是以图片作为参照系的,所以也要使用图片作为参照系
ActionChains(bro).move_to_element_with_offset(code_image_ele, x, y).click().perform()
bro.find_element_by_id('J-userName').send_keys("xxxxxxxxxxxx")
bro.find_element_by_id('J-password').send_keys('miludebeikeer')
bro.find_element_by_id('J-login').click()
第三方平台提供的代码(chaojiying.py)
#!/usr/bin/env python
# coding:utf-8
import requests
from hashlib import md5
class Chaojiying_Client(object):
def __init__(self, username, password, soft_id):
self.username = username
password = password.encode('utf-8')
self.password = md5(password).hexdigest()
self.soft_id = soft_id
self.base_params = {
'user': self.username,
'pass2': self.password,
'softid': self.soft_id,
}
self.headers = {
'Connection': 'Keep-Alive',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
}
def PostPic(self, im, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
}
params.update(self.base_params)
files = {'userfile': ('ccc.jpg', im)}
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
return r.json()
def ReportError(self, im_id):
"""
im_id:报错题目的图片ID
"""
params = {
'id': im_id,
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
return r.json()
if __name__ == '__main__':
chaojiying = Chaojiying_Client('超级鹰用户名', '超级鹰用户名的密码', '96001') #用户中心>>软件ID 生成一个替换 96001
im = open('a.jpg', 'rb').read() #本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
print(chaojiying.PostPic(im, 1902)) #1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()