zoukankan      html  css  js  c++  java
  • 12-基于selenium实现12306模拟登录,及京东登录滑动缺口验证模拟登录

    流程分析:

    • 使用selenium打开登录页面
    • 对当前selenium打开的这张页面进行截图
    • 对当前图片的局部区域(验证码图片区域)进行截图
      • 这样验证码图片和模拟登录进行所显示的图片一一对应(如果我们对图片发起请求每次请求都不一样无法准确定位及点击)
    • 使用超级鹰识别验证码图片(坐标)

    在这里插入图片描述
    在这里插入图片描述

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

    # -*- coding: utf-8 -*-
    from selenium import webdriver
    import time
    from PIL import Image
    from Chaojiying_Python import chaojiying
    from selenium.webdriver import ActionChains
    
    
    bro = webdriver.Chrome()
    url = "https://kyfw.12306.cn/otn/resources/login.html"
    bro.get(url)
    bro.implicitly_wait(5) #静默等待最大5秒,保证页面加载完毕
    time.sleep(1)
    bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
    bro.save_screenshot('aa.png')# save_screenshot 将当前页面进行截图保存
    
    # 确定验证码图片对应的左上角和右下角坐标(裁剪的区域就确定了)
    code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
    location = code_img_ele.location #  验证码图片左上角的坐标 x,y
    print("location:",location)
    size = code_img_ele.size # 验证码标签对应的长和宽
    print("size",size)
    

    在这里插入图片描述

    定位验证码图片左上角及右下角得坐标

    # -*- coding: utf-8 -*-
    from selenium import webdriver
    import time
    from PIL import Image
    from Chaojiying_Python import chaojiying
    from selenium.webdriver import ActionChains
    
    
    bro = webdriver.Chrome()
    url = "https://kyfw.12306.cn/otn/resources/login.html"
    bro.get(url)
    bro.implicitly_wait(5) #静默等待最大5秒,保证页面加载完毕
    time.sleep(1)
    bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
    bro.save_screenshot('aa.png')# save_screenshot 将当前页面进行截图保存
    
    # 确定验证码图片对应的左上角和右下角坐标(裁剪的区域就确定了)
    code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
    location = code_img_ele.location #  验证码图片左上角的坐标 x,y
    print("location:",location)
    size = code_img_ele.size # 验证码标签对应的长和宽
    print("size",size)
    # # 左下角和右下角坐标
    rangle = (int(location["x"]),int(location["y"]),int(location["x"] + size["width"]),int(location["y"] + size["height"]))
    print(rangle)
    

    在这里插入图片描述

    根据坐标区域进行裁剪

    # -*- coding: utf-8 -*-
    from selenium import webdriver
    import time
    from PIL import Image
    from Chaojiying_Python import chaojiying
    from selenium.webdriver import ActionChains
    
    
    bro = webdriver.Chrome()
    url = "https://kyfw.12306.cn/otn/resources/login.html"
    bro.get(url)
    bro.implicitly_wait(5) #静默等待最大5秒,保证页面加载完毕
    time.sleep(1)
    bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
    bro.save_screenshot('aa.png')# save_screenshot 将当前页面进行截图保存
    
    # 确定验证码图片对应的左上角和右下角坐标(裁剪的区域就确定了)
    code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
    location = code_img_ele.location #  验证码图片左上角的坐标 x,y
    print("location:",location)
    size = code_img_ele.size # 验证码标签对应的长和宽
    print("size",size)
    # # 左下角和右下角坐标
    rangle = (int(location["x"]),int(location["y"]),int(location["x"] + size["width"]),int(location["y"] + size["height"]))
    print(rangle)
    # 至此验证码图片的区域我们就确定下来了
    i = Image.open("aa.png")
    code_img_name = 'C:/Users/gpc/Desktop/python/Chaojiying_Python/12306.png'
    # crop 根据指定区域进行图片裁剪
    frame = i.crop(rangle)
    frame.save(code_img_name)# 保存
    

    在这里插入图片描述

    将验证码图片提交给超级鹰

    超级鹰的使用方法可参考: 07-爬虫验证码破解实战

    # -*- coding: utf-8 -*-
    from selenium import webdriver
    import time
    from PIL import Image
    from Chaojiying_Python import chaojiying
    from selenium.webdriver import ActionChains
    
    
    bro = webdriver.Chrome()
    url = "https://kyfw.12306.cn/otn/resources/login.html"
    bro.get(url)
    bro.implicitly_wait(5) #静默等待最大5秒,保证页面加载完毕
    bro.maximize_window()  # 窗口最大化
    time.sleep(1)
    bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
    bro.save_screenshot('aa.png')# save_screenshot 将当前页面进行截图保存
    
    # 确定验证码图片对应的左上角和右下角坐标(裁剪的区域就确定了)
    code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
    location = code_img_ele.location #  验证码图片左上角的坐标 x,y
    print("location:",location)
    size = code_img_ele.size # 验证码标签对应的长和宽
    print("size",size)
    # # 左下角和右下角坐标
    rangle = (int(location["x"]),int(location["y"]),int(location["x"] + size["width"]),int(location["y"] + size["height"]))
    print(rangle)
    # 至此验证码图片的区域我们就确定下来了
    i = Image.open("aa.png")
    code_img_name = 'C:/Users/gpc/Desktop/python/Chaojiying_Python/12306.png'
    # crop 根据指定区域进行图片裁剪
    frame = i.crop(rangle)
    frame.save(code_img_name)# 保存
    
    # 将验证码图片提交给超级鹰进行识别
    yanzhengma = chaojiying.Chaojiying_Client.tranformImgCode()
    print(yanzhengma)
    

    在这里插入图片描述

    点击验证码并登录账号

    # -*- coding: utf-8 -*-
    from selenium import webdriver
    import time
    from PIL import Image
    from Chaojiying_Python import chaojiying
    from selenium.webdriver import ActionChains
    
    
    bro = webdriver.Chrome()
    url = "https://kyfw.12306.cn/otn/resources/login.html"
    bro.get(url)
    bro.implicitly_wait(5) #静默等待最大5秒,保证页面加载完毕
    bro.maximize_window()  # 窗口最大化
    time.sleep(1)
    bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
    bro.save_screenshot('aa.png')# save_screenshot 将当前页面进行截图保存
    
    # 确定验证码图片对应的左上角和右下角坐标(裁剪的区域就确定了)
    code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
    location = code_img_ele.location #  验证码图片左上角的坐标 x,y
    print("验证码图片左上角坐标:",location)
    size = code_img_ele.size # 验证码标签对应的高和宽
    print("验证码图片的高和宽:",size)
    # # 左上角和右下角坐标
    rangle = (int(location["x"]),int(location["y"]),int(location["x"] + size["width"]),int(location["y"] + size["height"]))
    print("验证码图片左上角和右下角坐标:",rangle)
    # 至此验证码图片的区域我们就确定下来了
    i = Image.open("aa.png")
    code_img_name = 'C:/Users/gpc/Desktop/python/Chaojiying_Python/12306.png'
    # crop 根据指定区域进行图片裁剪
    frame = i.crop(rangle)
    frame.save(code_img_name)# 保存
    
    # 将验证码图片提交给超级鹰进行识别
    yanzhengma = chaojiying.Chaojiying_Client.tranformImgCode()
    print("超级鹰识别出来的待点击的坐标值:",yanzhengma)
    
    all_list = [] # 存储即将被点击的点坐标 [[x1,y1],[x2,y2]]
    if "|" in yanzhengma:
        list_1 = yanzhengma.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(yanzhengma.split(",")[0])
        y = int(yanzhengma.split(",")[1])
        xy_list = []
        xy_list.append(x)
        xy_list.append(y)
        all_list.append(xy_list)
    
    print(all_list)
    
    # 遍历位置列表,使用动作链对每一个列表元素对应的x,y指定的位置进行点击操作
    for l in all_list:
        x = l[0]
        y = l[1]
        ActionChains(bro).move_to_element_with_offset(code_img_ele,x,y).click().perform()#动作链
        time.sleep(0.5)
    
    # 输入用户名密码
    bro.find_element_by_id('J-userName').send_keys('18398141111')
    time.sleep(1)
    bro.find_element_by_id('J-password').send_keys('11111')
    time.sleep(1)
    bro.find_element_by_id('J-login').click()
    
    #bro.quit()#退出
    
    

    在这里插入图片描述

    在这里插入图片描述

    滑动模块破解

    加入动作链滑动代码如下

    # -*- coding: utf-8 -*-
    from selenium import webdriver
    import time
    from PIL import Image
    from Chaojiying_Python import chaojiying
    from selenium.webdriver import ActionChains
    
    
    bro = webdriver.Chrome()
    url = "https://kyfw.12306.cn/otn/resources/login.html"
    bro.get(url)
    bro.implicitly_wait(5) #静默等待最大5秒,保证页面加载完毕
    bro.maximize_window()  # 窗口最大化
    time.sleep(1)
    bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
    bro.save_screenshot('aa.png')# save_screenshot 将当前页面进行截图保存
    
    # 确定验证码图片对应的左上角和右下角坐标(裁剪的区域就确定了)
    code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
    location = code_img_ele.location #  验证码图片左上角的坐标 x,y
    print("验证码图片左上角坐标:",location)
    size = code_img_ele.size # 验证码标签对应的高和宽
    print("验证码图片的高和宽:",size)
    # # 左上角和右下角坐标
    rangle = (int(location["x"]),int(location["y"]),int(location["x"] + size["width"]),int(location["y"] + size["height"]))
    print("验证码图片左上角和右下角坐标:",rangle)
    # 至此验证码图片的区域我们就确定下来了
    i = Image.open("aa.png")
    code_img_name = 'C:/Users/gpc/Desktop/python/Chaojiying_Python/12306.png'
    # crop 根据指定区域进行图片裁剪
    frame = i.crop(rangle)
    frame.save(code_img_name)# 保存
    
    # 将验证码图片提交给超级鹰进行识别
    yanzhengma = chaojiying.Chaojiying_Client.tranformImgCode()
    print("超级鹰识别出来的待点击的坐标值:",yanzhengma)
    
    all_list = [] # 存储即将被点击的点坐标 [[x1,y1],[x2,y2]]
    if "|" in yanzhengma:
        list_1 = yanzhengma.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(yanzhengma.split(",")[0])
        y = int(yanzhengma.split(",")[1])
        xy_list = []
        xy_list.append(x)
        xy_list.append(y)
        all_list.append(xy_list)
    
    print("被点击的坐标位置:",all_list)
    
    # 遍历位置列表,使用动作链对每一个列表元素对应的x,y指定的位置进行点击操作
    for l in all_list:
        x = l[0]
        y = l[1]
        ActionChains(bro).move_to_element_with_offset(code_img_ele,x,y).click().perform()#动作链
        time.sleep(0.5)
    
    # 输入用户名密码
    bro.find_element_by_id('J-userName').send_keys('18398141111')
    time.sleep(1)
    bro.find_element_by_id('J-password').send_keys('11111')
    time.sleep(1)
    bro.find_element_by_id('J-login').click()
    
    # 加入动作链
    div_tag = bro.find_element_by_xpath('//*[@id="nc_1_wrapper"]')
    
    # 对div_tag进行滑动操作
    action = ActionChains(bro) #实例化一个动作对象
    action.click_and_hold(div_tag) # 点击且长按不放
    
    for i in range(6):
        # perform 让动作链立即执行
        action.move_by_offset(20,0).perform() #偏移x20像素,y0像素
        time.sleep(0.1)
    action.release()
    
    
    
    
    #bro.quit()#退出
    

    结果如下:
    在这里插入图片描述

    京东缺口滑动验证码

    # -*- coding: utf-8 -*-
    from collections import Counter
    from PIL import Image
    from selenium import webdriver
    import time
    from selenium.webdriver.common.action_chains import ActionChains
    
    class JDlogin():
        def __init__(self):#定义函数,链接登录页面
            self.driver = driver = webdriver.Chrome()#启动调试工具
            self.driver.get('https://passport.jd.com/new/login.aspx')#获取JD登陆页面
            self.driver.implicitly_wait(5)  # 静默等待最大5秒,保证页面加载完毕
            time.sleep(2)
    
    
        def get_picture(self):#获取图片
        #通过xpath寻找按键点击“账户登陆”
            self.driver.find_element_by_xpath('.//div[@class="login-tab login-tab-r"]/a').click()
            time.sleep(1)
            #定位账号输入框
            self.driver.find_element_by_xpath('.//input[@id="loginname"]').send_keys('账号')
            time.sleep(1)
            #定位密码输入框
            self.driver.find_element_by_xpath('.//input[@id="nloginpwd"]').send_keys('密码')
            time.sleep(1)
            #定位登陆按钮,并点击,此时会展示出验证码图片
            self.driver.find_element_by_xpath('.//div[@class="login-btn"]/a').click()
            time.sleep(1)
            #通过修改JS隐藏滑块并截屏获取验证码图片,保存至当前目录,名为slice.png(双层图也是这么干,不过ClassName与xpath需要改动)
            js = 'document.getElementsByClassName("JDJRV-smallimg")[0].style.display="none"'
            self.driver.execute_script(js)
            slice_path = './slice.png'
            self.driver.find_element_by_xpath('.//div[@class="JDJRV-bigimg"]').screenshot(slice_path)
            time.sleep(1)
            #停止1秒后恢复JS改动,回到页面最初状态(双层图亦然)
            js = 'document.getElementsByClassName("JDJRV-smallimg")[0].style.display="block"'
            self.driver.execute_script(js)
    
    #将获得的验证码图片进行处理(灰度化、二值化、降噪)
    #双层图可以直接进行两张图片的比较,而单层图则需要处理之后进行自身比较,本案例为单层图事例
    
        def shape(self, w, h, image):  # 二值化,将所有的点位,全部换成0或255
            tem = 0
            for x in range(w):
                for y in range(h):
                    tem += image.getpixel((x, y))
            pixel_ave = tem / w / h * 0.7
            for x in range(w):
                for y in range(h):
                    p = image.getpixel((x, y))
                    if p < pixel_ave:
                        image.putpixel((x, y), 0)
                    else:
                        image.putpixel((x, y), 255)
            return image
    
        def reducenoise(self, image):#降噪处理
            w, h = image.size
            for x in range(0, 40):  # 处理最左边
                for y in range(h):
                    image2 = image.putpixel((x, y), 255)
            return image
    
        def make_picture(self):  # 处理图片,灰度化与二值化、降噪
            im = Image.open('slice.png')
            im2 = im.convert("L")
            w, h = im2.size
            im3 = self.shape(w, h, im2)
            im4 = self.reducenoise(im3)
            return im3
    
    #计算验证图片左边边界到缺口左边边界的距离(即滑块拖动距离)
    
        def get_juli(self, image):  # 计算距离
            w, h = image.size
            ls = []
            for i in range(31, w - 31):#图片最左边放置滑块,缺口坐标x不可能小于31
                for j in range(10, h):
                    if image.getpixel((i, j)) < 100:
                        count = 0
                        for k in range(i, i + 31):
                            if image.getpixel((k, j)) < 100:
                                count += 1
                            else:
                                break
                        if count > 27: ls.append(i)
    
            return Counter(ls).most_common(1)[0][0]
    
    #设计拖动轨迹
        def get_track(self, distance):  # 设计拖动轨迹
            ls = [1]
            while 1:
                i = ls[-1] * 2
                ls.append(i)
                if sum(ls) > distance * 0.7:
                    break
    
            ls.append(int(distance - sum(ls)))
    
            return ls
        
    #通过selenium执行拖动滑块的指令,实现验证登陆
        def drog_btn(self, track):  # 拖动滑块
        #定位滑块
            ele = self.driver.find_element_by_xpath('.//div[@class="JDJRV-slide-inner JDJRV-slide-btn"]')
            #设计拖动动作链(点击且不放)
            ActionChains(self.driver).click_and_hold(ele).perform()
            #根据设计的轨迹,实现滑块拖动
            for i in track:
                ActionChains(self.driver).move_by_offset(i, 0).perform()#鼠标从当前位置移动到某个坐标
        #睡眠0.25秒,伪装成人的等一下松开鼠标的操作
                time.sleep(0.25)
            #释放滑块,类似于松开鼠标
            ActionChains(self.driver).release().perform()
            time.sleep(2)
    
    
    
    
    
        def check(self):#再次尝试
            self.get_picture()
            image = self.make_picture()
            distance = self.get_juli(image)
            track = self.get_track(distance)
            self.drog_btn(track)
    
    
    if __name__ == '__main__':
        login = JDlogin()
        login.get_picture()
        image = login.make_picture()
        distance = login.get_juli(image)
        track = login.get_track(distance)
        login.drog_btn(track)
        time_int = 0
        while time_int < 5:
            input("是否需要再次尝试")
            login.driver.refresh()
            login.check()
            time_int += 1
    
    

    ActionChains动作链方法列表

    click(on_element=None) ——单击鼠标左键
    click_and_hold(on_element=None) ——点击鼠标左键,不松开
    context_click(on_element=None) ——点击鼠标右键
    double_click(on_element=None) ——双击鼠标左键
    drag_and_drop(source, target) ——拖拽到某个元素然后松开
    drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开
    key_down(value, element=None) ——按下某个键盘上的键
    key_up(value, element=None) ——松开某个键
    move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标
    move_to_element(to_element) ——鼠标移动到某个元素
    move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置
    perform() ——执行链中的所有动作
    release(on_element=None) ——在某个元素位置松开鼠标左键
    send_keys(*keys_to_send) ——发送某个键到当前焦点的元素
    send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素
    
  • 相关阅读:
    剑指Offer_08_跳台阶
    剑指Offer_07_斐波那契数列
    HDU 4283 You Are the One
    1B. Spreadsheets
    1A Theatre Square
    HDU 2476 String painter(记忆化搜索, DP)
    LightOJ 1422 Halloween Costumes(记忆化搜索)
    POJ 1651 Multiplication PuzzleDP方法:
    POJ 2955 Brackets (区间DP)
    HDU 5452 Minimum Cut
  • 原文地址:https://www.cnblogs.com/gemoumou/p/13635333.html
Copyright © 2011-2022 走看看