用selenium对12306模拟登录

上一篇 selenium模块的基本使用: https://blog.csdn.net/qq_43401941/article/details/109152031

一、超级鹰的使用

https://www.chaojiying.com/

  1. 注册:普通用户

  2. 登录:普通用户

  3. 题分查询:充值(1块=1000题分)

    用selenium对12306模拟登录_第1张图片

  4. 进入用户中心 -> 软件ID -> 生成一个软件ID

    用selenium对12306模拟登录_第2张图片

  5. 下载示例代码 :开发文档 -> 根据对应的开发语言选择下载,这里我选择的是python -> 进入点击下载,保存到本地

    用selenium对12306模拟登录_第3张图片

  6. 解压 -> 解压出来的有一张图片 a.jpg,示例代码 chaojiying.py

  7. 在 pychram中新建一个测试模块,将chaojiying.py和 a.jpg拷入进去。对chaojiying代码进行格式缩进

    用selenium对12306模拟登录_第4张图片

  8. 在超级鹰首页中可查看价格体系,选择对应的验证码类型。

    用selenium对12306模拟登录_第5张图片

  9. 运行程序代码

    用selenium对12306模拟登录_第6张图片


12306模拟登录编码流程:

  1. 使用selenium打开登录页面https://kyfw.12306.cn/otn/resources/login.html

  2. 对当前selenium打开的这张页面进行截图

  3. 对当前图片局部区域(验证码区域)进行裁剪

    这样做的好处就是将验证码图片和模拟登录操作进行一一对应。如果单独对这张验证码图片进行请求,那么可能拿到的解析验证码与当前的模拟登录验证码图片不符。

  4. 使用超级鹰识别验证码图片(坐标)

    这里选择坐标验证码类型,是因为超级鹰平台识别给我们返回的是“文字”所对应的“坐标”,比如这里接受到“雨靴”,“棉棒”这样的关键字之后,返回的是关键字所对应的图片坐标。

    用selenium对12306模拟登录_第7张图片

代码示例:

chaojiying.py

""" 1.使用 selenium打开登录页面 """
from selenium import webdriver
from selenium.webdriver import ChromeOptions
from time import sleep
from PIL import Image  # pip install Pillow

# 实现规避检测
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])

browser = webdriver.Chrome(executable_path='./chromedriver', options=option)
browser.get('https://kyfw.12306.cn/otn/resources/login.html')
# 点击账号登录
account_login = browser.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]')
account_login.click()
browser.maximize_window()  # 将浏览器最大化显示
sleep(1)

""" 2.save_screenshot对当前页面进行截图且保存 """
browser.save_screenshot('./12306html.png')

# 确定验证码图片对应的左上角和右下角的坐标(确定裁剪的区域)
code_img_ele = browser.find_element_by_xpath('/html/body/div[2]/div[2]/div[1]/div[2]/div[3]/div')  # 定位到验证码区域
location = code_img_ele.location  # 验证码图片左上角的坐标 x,y
print("location: ", location)
size = code_img_ele.size  # 验证码图片对应的长和宽 height,width
print("size: ", size)
# 左上角和右下角的坐标
# 这里坐标乘 1.25是由于电脑屏幕的比例不是100%,我的是125%,可以在显示设置中查看
local = (
    int(location['x'] * 1.25), int(location['y'] * 1.25),
    int((location['x'] + size['width']) * 1.25), int((location['y'] + size['height']) * 1.25)
)

img = Image.open('./12306html.png')
code_img_name = './code.png'
frame = img.crop(local)  # 3.根据指定区域进行裁剪
frame.save(code_img_name)  # 对裁剪下来的区域进行保存

截图位图不正确,是由于电脑屏幕的比例不是100%,我的是125%,可以在显示设置中查看

将坐标位置 乘1.25 即可

用selenium对12306模拟登录_第8张图片

将验证码图片交给超级鹰进行识别

""" 4. 将验证码图片交给超级鹰进行识别 """
chaojiying = Chaojiying_Client('超级鹰用户名', '超级鹰用户名的密码', '96001')  # 用户中心>>软件ID 生成一个替换 96001
im = open('code.png', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
print(chaojiying.PostPic(im, 9004)['pic_str'])  # 1902 验证码类型  官方网站>>价格体系 3.4+版 print 后要加()

用selenium对12306模拟登录_第9张图片

  1. 将返回的坐标存储到 all_list 列表中,然后遍历列表获取(x, y)坐标,使用动作链进行自动点击
from selenium.webdriver import ActionChains  # 导入动作链对应的类

all_list = []  # 存储要被点击的坐标
if '|' in result:
    list_1 = result.split('|')
    count_1 = len(list_1)
    # 因为 list_1 = [['x1,y1'], ['x2, y2']]存储的是字符,所以遍历将每个元素转为 int
    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:
    xy_list = []
    x = int(result.split(',')[0])
    y = int(result.split(',')[1])
    xy_list.append(x)
    xy_list.append(y)
    all_list.append(xy_list)

# 遍历列表,使用动作链对每个元素对应的(x,y)坐标指定的位置进行点击操作
# 动作链 (拖动)
action = ActionChains(browser)
for coor in all_list:
    x = coor[0]
    y = coor[1]
    # 切换到页面中的验证码图片区域,进行点击
    action.move_to_element_with_offset(code_img_ele, x, y).click().perform()
    sleep(0.5)
  1. 获取用户名和密码输入框标签,进行用户名和密码的输入,然后点击登录按钮进行登录
username = browser.find_element_by_id('J-userName')
password = browser.find_element_by_id('J-password')
login_btn = browser.find_element_by_id('J-login')
username.send_keys('17671374607')
sleep(0.5)
password.send_keys('wb123456789')
sleep(0.5)
login_btn.click()
sleep(1)
  1. 滑块验证处理
# 滑块验证
# 标签定位
div_tag = browser.find_element_by_id('nc_1_wrapper')
slider = browser.find_element_by_id('nc_1_n1z')

# 进行滑动操作
action = ActionChains(browser)  # 实例化一个动作对象
action.click_and_hold(slider)  # 点击且长按不放
# drag_and_drop_by_offset(source, x:水平, y:垂直) 拖拽到某个坐标然后松开,perform()立即执行动作链操作
action.drag_and_drop_by_offset(div_tag, 300, 0).perform()
sleep(0.3)
# 释放动作链
action.release()

完整代码示例:

#!/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('utf8')
        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 后要加()

""" 1.使用 selenium打开登录页面 """
from selenium import webdriver
from selenium.webdriver import ChromeOptions
from time import sleep
from PIL import Image  # pip install Pillow
from selenium.webdriver import ActionChains  # 导入动作链对应的类

# 实现规避检测
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])

browser = webdriver.Chrome(executable_path='./chromedriver', options=option)
browser.get('https://kyfw.12306.cn/otn/resources/login.html')
# 点击账号登录
account_login = browser.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]')
account_login.click()
browser.maximize_window()  # 将浏览器最大化显示
sleep(1)

""" 2.save_screenshot对当前页面进行截图且保存 """
browser.save_screenshot('./12306html.png')

# 确定验证码图片对应的左上角和右下角的坐标(确定裁剪的区域)
code_img_ele = browser.find_element_by_id('J-loginImg')  # 定位到验证码图片标签区域
location = code_img_ele.location  # 验证码图片左上角的坐标 x,y
print("location: ", location)
size = code_img_ele.size  # 验证码图片对应的长和宽 height,width
print("size: ", size)
# 左上角和右下角的坐标
# 这里坐标乘 1.25是由于电脑屏幕的比例不是100%,我的是125%,可以在显示设置中查看
local = (
    int(location['x'] * 1.25), int(location['y'] * 1.25),
    int((location['x'] + size['width']) * 1.25), int((location['y'] + size['height']) * 1.25)
)

img = Image.open('./12306html.png')
code_img_name = './code.png'
frame = img.crop(local)  # 3.根据指定区域进行裁剪
frame.save(code_img_name)  # 对裁剪下来的区域进行保存

""" 4. 将验证码图片交给超级鹰进行识别 """
chaojiying = Chaojiying_Client('17671374607', 'chaojiying123456789', '908913')  # 用户中心>>软件ID 生成一个替换 96001
im = open('code.png', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
print(chaojiying.PostPic(im, 9004)['pic_str'])  # 1902 验证码类型  官方网站>>价格体系 3.4+版 print 后要加()
result = chaojiying.PostPic(im, 9004)['pic_str']

all_list = []  # 存储要被点击的坐标
if '|' in result:
    list_1 = result.split('|')
    count_1 = len(list_1)
    # 因为 list_1 = [['x1,y1'], ['x2, y2']]存储的是字符,所以遍历将每个元素转为 int
    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:
    xy_list = []
    x = int(result.split(',')[0])
    y = int(result.split(',')[1])
    xy_list.append(x)
    xy_list.append(y)
    all_list.append(xy_list)

# 遍历列表,使用动作链对每个元素对应的(x,y)坐标指定的位置进行点击操作
# 动作链 (拖动)
action = ActionChains(browser)
for coor in all_list:
    x = coor[0]
    y = coor[1]
    # 切换到页面中的验证码图片区域,进行点击
    # 将坐标乘 0.8是对应原始页面的验证码图片区域坐标
    action.move_to_element_with_offset(code_img_ele, int(x * 0.8), int(y * 0.8)).click().perform()
    sleep(0.3)
# 释放动作链
action.release()

username = browser.find_element_by_id('J-userName')
password = browser.find_element_by_id('J-password')
login_btn = browser.find_element_by_id('J-login')
username.send_keys('17671374607')
sleep(0.5)
password.send_keys('wb123456789')
sleep(0.5)
login_btn.click()
sleep(1)

# 滑块验证
# 标签定位
div_tag = browser.find_element_by_id('nc_1_wrapper')
slider = browser.find_element_by_id('nc_1_n1z')

# 进行滑动操作
action = ActionChains(browser)  # 实例化一个动作对象
action.click_and_hold(slider)  # 点击且长按不放
# drag_and_drop_by_offset(source, x:水平, y:垂直) 拖拽到某个坐标然后松开,perform()立即执行动作链操作
action.drag_and_drop_by_offset(div_tag, 300, 0).perform()
sleep(0.3)
# 释放动作链
action.release()

sleep(10)
browser.quit()

超级鹰识别并不是完全正确,还有滑块验证老是错误,需要重新试一下,难道是检测出来了是爬虫程序????

你可能感兴趣的:(Python,python,selenium,chrome,列表)