selenium 综合应用 (2)
需求
模拟登录 12306
注意:目的在于验证码的识别。因为除了点击,12306在登录后还存在滑块验证码。本篇文章并不涉及滑块验证码。
代码分析
首先需要定位并点击 “账号登陆”
然后问题就是账号密码和验证码的问题了。
我相信账号密码并不是什么大问题,实际上叫人无从下手的是验证码问题。这时候需要的就是我们的验证码网站了。
12306 网站的验证码基本是 1~4 个坐标,所以我们选择 type = 27。
需要明白的是我们使用验证码识别的是坐标。
所以我们需要做的是获取验证码的图片,这时候我们不能使用以前用的方法,因为通过网址获取的验证码是动态更新的。所以我们需要对验证码部分使用代码进行截图。(这部分比较麻烦,如果有必要的话,甚至可以直接 CTRL + C 然后 CTRL + V)
需要注意的是因为我的电脑是文本显示大小是125%,所以相应的数据需要乘以或是除以 1.25。
代码实现
from selenium import webdriver
from time import sleep
from PIL import Image
import base64
import json
import requests
from selenium.webdriver import ActionChains # 动作链
def base64_api(uname, pwd, img, typeid):
with open(img, 'rb') as f:
base64_data = base64.b64encode(f.read())
b64 = base64_data.decode()
data = {"username": uname, "password": pwd,"typeid":typeid, "image": b64}
result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text)
if result['success']:
return result["data"]["result"]
else:
return result["message"]
return ""
if __name__ == '__main__':
bor = webdriver.Chrome("chromedriver.exe")
bor.get("https://kyfw.12306.cn/otn/resources/login.html")
# 定位“账号登录”并点击
btn = bor.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a')
bor.execute_script("arguments[0].click()", btn)
sleep(5)
# 输入账号密码
user_name = bor.find_element_by_id("J-userName")
user_name.send_keys("")
password = bor.find_element_by_id("J-password")
password.send_keys("")
# 对整个页面截图并保存
bor.maximize_window() # 窗口最大化
photo = bor.save_screenshot("窗口截图.png")
# 定位坐标位置
img = bor.find_element_by_id('J-loginImg')
location = img.location # 验证码图片左上角坐标。X, Y
# print("location", location)
size = img.size # 验证码标签对应的长宽
print("size", size)
rangle = (location["x"]*1.25, location["y"]*1.25, (location["x"] + size["width"])*1.25, (location["y"] + size["height"])*1.25)
# 裁剪
i = Image.open('窗口截图.png')
# 对指定位置进行裁剪
fram = i.crop(rangle)
fram.save('验证码.png')
# 识别验证码
img_path = "C:\\Users\\ASUS\\Desktop\\CSDN\\selenium 模块\\验证码.png"
result = base64_api(uname='', pwd='', img=img_path, typeid=27)
print(result)
# 确定要点击的位置
if "|" in result:
index_list = result.split('|')
x_list = []
y_list = []
for xy in index_list:
xy_list = xy.split(",")
x_list.append(xy_list[0])
y_list.append(xy_list[1])
else:
x_list = []
y_list = []
xy_list = result.split(",")
x_list.append(xy_list[0])
y_list.append(xy_list[1])
print(x_list, y_list)
for i in range(len(x_list)):
x = int(int(x_list[i]) // 1.25)
y = int(int(y_list[i]) // 1.25)
ActionChains(bor).move_to_element_with_offset(img, int(x), int(y)).click().perform()
sleep(2)
# 点击登录
btn_login = bor.find_element_by_id('J-login')
bor.execute_script('arguments[0].click()', btn_login)
sleep(10)
bor.quit()