一、准备工作
- 下载 selenium 包
pip install selenium
- 下载浏览器自动化测试工具 webdriver(点击跳转下载)
二、 selenium 访问页面获取验证码图片
- 通过 selenium 爬取 12306 登录页并截图
import requests
from selenium import webdriver
from PIL import Image
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
bro = webdriver.Chrome(executable_path='./chromedriver.exe') # 打开一个自动化谷歌浏览器
bro.maximize_window() # 浏览器全屏
bro.get('https://kyfw.12306.cn/otn/login/init') # 在谷歌浏览器中访问网站
bro.save_screenshot('12306_login.png') # 截取浏览器并保存
12306_login.png :
- 获取图片验证码位置
img_tag = bro.find_element_by_xpath('//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img')
location = img_tag.location # 左下角坐标
size = img_tag.size # 图片尺寸
rangle = [location['x'],location['y'],location['x']+size['width'],location['y']+size['height']] # 截图坐标
i = Image.open('./12306_login.png')
frame = i.crop(rangle)#根据裁剪的范围进行裁剪
frame.save('code.png')
code.png :
截图之后才发现怪怪的,跟验证码图片的位置对不上,反复试了几次都这样,查了半天发现是电脑的显示比例是125%
查了一种可以自动获取电脑缩放比例的方法(传送门:获取屏幕真实分辨率、缩放后的分辨率以及缩放比例),需要的可以按照该操作处理一下,我直接将缩放比例写在代码里。
screen_scale_rate = 1.25 # 屏幕缩放率
img_tag = bro.find_element_by_xpath('//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img')
location = img_tag.location # 左下角坐标
size = img_tag.size # 图片尺寸
# rangle = [location['x'],location['y'],location['x']+size['width'],location['y']+size['height']] # 100%显示率截图坐标
rangle = [int(i*screen_scale_rate) for i in [location['x'],location['y'],location['x']+size['width'],location['y']+size['height']]] # 增加屏幕缩放率截图坐标
i = Image.open('./12306_login.png')
frame = i.crop(rangle) # 根据裁剪的范围进行裁剪
frame.save('code.png')
code.png :
三、将验证码图片发送给验证码识别平台
# 验证码识别,返回点击坐标
result = getCode_text('code.png',9004)
print(result) #:x1,y1|x2,y2|x3,y3
#将result转换成[[x1,y1],[x2,y2]]
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)
四、
# 将返回的坐标在浏览器中点击出来
for loc in all_list:
x = loc[0]
y = loc[1]
ActionChains(bro).move_to_element_with_offset(img_tag,x,y).click().perform()
sleep(1)
bro.find_element_by_id('username').send_keys('1234567890@qq.com')
sleep(1)
bro.find_element_by_id('password').send_keys('0000000000')
sleep(1)
#验证码的处理
bro.find_element_by_id('loginSub').click()
sleep(3)
bro.quit() # 关闭浏览器