zoukankan      html  css  js  c++  java
  • selenium模拟登录12306官网 +超级鹰识别验证码

    前言

    超级鹰开发文档: http://www.chaojiying.com/api.html
    我这里用的python,点击下载就好了。

    一、通过selenium自动登录12306官网

    from selenium import webdriver
    from time import sleep
    from PIL import Image
    from selenium.webdriver import ActionChains
    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()
    
    driver=webdriver.Chrome(executable_path=r'./chromedriver')
    driver.maximize_window() #全屏
    ## 打开12306官网
    driver.get('https://kyfw.12306.cn/otn/resources/login.html')
    #选择账号登陆并点击
    driver.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
    sleep(2)
    #截屏整张图,后续找到验证码的坐标,做裁剪
    driver.save_screenshot('./12306.png')
    
    #确定验证码图片的左上角和右下角的坐标(裁剪区域就确定了)
    code_img_ele = driver.find_element_by_xpath('//*[@id="J-loginImg"]')
    location = code_img_ele.location #验证码图片左上角的坐标{'x': 766, 'y': 284}
    size=code_img_ele.size #验证码标签对应的长和宽  #{'height': 188, 'width': 300}
    print(location,size)
    #左上角和右下角的坐标,元组的形式存储,后续截取 电脑分辨率默认为125%
    rangle = (
        int(location['x'])*1.25,int(location['y'])*1.25,int((location['x']+size['width'])*1.25),int((location['y']+size['height'])*1.25),
    )
    print(rangle)
    code_img_name ='./code.png'
    #裁剪验证码并保存
    img = Image.open('./12306.png')
    frame=img.crop(rangle)
    frame.save(code_img_name)
    
    #超级鹰识别
    chaojiying = Chaojiying_Client('账号', '密码', '904142')  # 用户中心>>软件ID 生成一个替换 904142
    im = open('./code.png', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    # 返回验证码需点击的坐标对象
    result = chaojiying.PostPic(im, 9004)['pic_str']  #验证码类型  官方网站>>价格体系 3.4+版 print 后要加()
    
    # 创建坐标数据结构
    all_list = []  #[[140,166],[59,173],]
    if '|' in result: #140,166|59,173
        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)
    
    #动作链作移动定位时,需要等比缩小25%即可
    for list in all_list:
        x = list[0]*0.85
        y = list[1]*0.85
        # 实例化动作链并立即执行移动操作
        action=ActionChains(driver)
        #以code_img_ele验证码标签为参照物
        action.move_to_element_with_offset(code_img_ele,x,y).click().perform()
        sleep(0.5)
    # 获取到输入框 用户名
    driver.find_element_by_id('J-userName').send_keys('xxx@qq.com')
    # 获取到输入框 密码
    driver.find_element_by_id('J-password').send_keys('xxx...')
    sleep(1)
    # 点击登录
    driver.find_element_by_id('J-login').click()
    sleep(2)
    #下载界面
    page_text = driver.page_source
    with open("12306.html", "w", encoding="utf-8") as fp:
        fp.write(page_text)
    
    sleep(3)
    driver.quit()
    

    二、python+selenium+Chromedriver使用location定位元素坐标偏差的问题

    使用xpath定位元素,用.location获取坐标值,截取网页截图的一部分出现偏差。

    之所以会出现这个坐标偏差是因为windows系统下电脑设置的显示缩放比例造成的(一般默认是125%),location获取的坐标是按显示100%时得到的坐标,而截图所使用的坐标却是需要根据显示缩放比例缩放后对应的图片所确定的,因此就出现了偏差。
    解决这个问题有三种方法:
    1.修改电脑显示设置为100%。这是最简单的方法;
    2.缩放截取到的页面图片,即将截图的size缩放为宽和高都除以缩放比例后的大小(坐标大小*1.25);
    3.修改Image.crop的参数,将参数元组的四个值都乘以缩放比例。
    上面代码的实现是用的方法 ② ③

    # 以当前电脑125%缩放比为例
    rangle = (int(location_position["x"]*1.25), int(location_position["y"]*1.25),
              int((location_position["x"] + img_size["width"])*1.25),
              int((location_position["y"] + img_size["height"])*1.25))
    
    # 动作链作移动定位时,需要等比缩小25%即可
    for lis in all_list:
        x = lis[0]*0.85
        y = lis[1]*0.85
        # 实例化动作链并立即执行移动操作
        ActionChains(dri).move_to_element_with_offset(code_img, x, y).click().perform()
        sleep(0.5)
    

    参考:
    https://blog.csdn.net/weixin_43751840/article/details/88423031
    https://www.cnblogs.com/WiseAdministrator/articles/11318122.html

  • 相关阅读:
    C# 关于调用微信接口的代码
    Winform实现微信功能
    Delphi 7 在IDE菜单中增加UPX工具
    Delphi7中Unicode,ANSI,UTF编码问题
    本机时间不正确带来的问题
    Delphi最简化异步选择TCP服务器
    C# Winform小程序:局域网设置NTP服务器、实现时间同步
    开源Inno Setup官网下载、安装、打包教程(官网安装向导中文语言包)
    css 雪碧图的制作
    原生js 实现的瀑布流
  • 原文地址:https://www.cnblogs.com/hanfe1/p/12553812.html
Copyright © 2011-2022 走看看