11、Python Selenium操作模拟登录12306中国铁路

  • 一组连续的操作就是动作链
    • 滑动:鼠标点击长按之后进行偏移

1、示例代码引入

from selenium import webdriver
from time import sleep
from selenium.webdriver import ActionChains  #动作链


# 实例化一个浏览器对象
bro = webdriver.Chrome(executable_path='./chromedriver.exe')
# 发送请求
bro.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')

sleep(1)
#如果定位的标签是标签嵌套存在于iframe标签之下的,则需要使用switch_to的操作进行标签定位
bro.switch_to.frame('iframeResult')
# 定位标签属性 
div_tag = bro.find_element_by_xpath('//*[@id="draggable"]')

# 实例化动作链对象
action = ActionChains(bro)
# 点击且长按一个标签
action.click_and_hold(div_tag)

for i in range(5):
    #move_by_offset设置偏移量,perform可以让动作链立即执行
    action.move_by_offset(10,10).perform()
#     sleep(2)

# 对div_tag进行滑动

bro.quit()

效果GIF图:

2、12306模拟登录

​ 实现流程
​ 可以对登录首页进行截图,在通过裁剪的操作将验证码图片进行获取
​ 验证码图片提交给打码平台进行识别
环境安装:
pip install PIL #进行图片裁剪模块,或者安装pip install Pillow , Pillow是PIL的升级版

pip install selenium

pip install requests

from selenium import webdriver
from time import sleep
from selenium.webdriver import ActionChains  #动作链
from PIL import Image
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__':
    def transform_codeImg(imgPath,imgType):
        chaojiying = Chaojiying_Client('xjs2020', 'xxx', '905940')	#超级鹰用户名,密码,ID:超级鹰用户中心>>软件ID 生成一个替换 96001
        im = open(imgPath, 'rb').read()#本地图片文件路径 来替换 a.jpg 有时WIN系统须要
        return chaojiying.PostPic(im, imgType)['pic_str']#1902 验证码类型  


    # 实例化一个浏览器对象
    bro = webdriver.Chrome(executable_path='./chromedriver.exe')
    bro.maximize_window()#浏览器全屏显示
    # 发送请求
    bro.get('https://kyfw.12306.cn/otn/resources/login.html')
    sleep(0.5)
    # 点击一下使用账号密码登录
    bro.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
    sleep(0.5)
    # 首页截图
    bro.save_screenshot('./main.png')
    #将验证码图片进行裁剪

    img_tag = bro.find_element_by_xpath('//*[@id="J-loginImg"]')#定位到验证码图标属性
    location = img_tag.location #img_tag标签在页面中的起始位置(x,y)
    # print(location)   #{'x': 712, 'y': 284}
    size = img_tag.size #img_tag在页面中显示的尺寸包含长宽
    # print(size)       #{'height': 188, 'width': 300}
    #存储验证码图片左下角和右上角的坐标
    rangle = (int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height']))
    #根据rangle进行验证码的裁剪
    i = Image.open('./main.png')
    frame = i.crop(rangle)#根据rangle进行指定区域裁剪
    frame.save('./code.png')

    #将验证码图片提交给超级鹰
    result = transform_codeImg('./code.png',9004)
    #将170,70|4,150转换成[[170,70],[4,150]]
    all_list = []#[[170,70],[4,150]]
    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()#通过定位到验证码图标属性进行位置滑动,perform立即执行
        #ActionChains(bro).move_by_offset(x,y)#注意:此方法不可取,他是针对整张页面进行滑动
        sleep(1)
        
    user_tag = bro.find_element_by_id('J-userName')
    user_tag.send_keys('15801500903')            #12306用户名
    pwd_tag = bro.find_element_by_id('J-password')
    pwd_tag.send_keys('xxx')                     #12306密码
    sleep(2)
    bro.find_element_by_id('J-login').click()
    sleep(6)
    bro.quit()

效果GIF图

原文地址:https://www.cnblogs.com/remixnameless/p/13172930.html