通过PyAutoGUI+DrissionPage+Cv2,实现滑块的自动验证

访问网页时,每次都需要输入验证码,真的是太麻烦了

每次查询快递的时候,都需要进行验证,不是要输入验证码就是要滑块,那么有没有办法不用那么麻烦呢?当然是有的,要么是和快递公司进行接口对接,要么就是通过快递公司官网进行查询。

作为一个技术的爱好者,也作为一个顺丰快递粉丝,那么就以顺丰快递为例来进行一次技术的可行性研究吧。如果要进行技术对接,可以参考顺丰丰桥的接口即可。这里研究通过顺丰官网的方式来实现快递单号的自动查询。

首先我们要找到顺丰的官网。顺丰官网

在顺丰查询快递单号时,需要通过滑块的滑动来实现验证,那么实现自动查单号路由的难点就是要实现滑块的自动拖拽。

那么我们来整理一下思路和步骤:

1、访问顺丰的官网

顺丰的官方网址:顺丰官网

2、找到单号输入框并自动输入快递单号

3、检索路由,出现滑块拼图弹框出现

4、难点:解决滑块图片的下载、位置的计算、滑块的拖动

5、获取检索结果

那么我们下面就开始进行实现的验证吧。

从个人喜欢用的工具和库来说,

①:我选择用DrissionPage来替代Selenium 来实现对应浏览器的访问和数据获取

②:模拟人工拖拉滑块的动作,使用PyAutoGUI来实现

③:使用Cv2来计算图片位置的计算

1、首先引入需要用到的模块:

import pyautogui
from time import sleep
from DrissionPage import ChromiumPage
import time
import requests
import cv2

pyautogui.PAUSE = 1  # 调用在执行动作后暂停的秒数,只能在执行一些pyautogui动作后才能使用,建议用time.sleep

2、使用浏览器访问目标网址

# 打开目标页面
def openBrowserPage():
    page.get('https://www.sf-express.com/chn/sc')
    sleep(1.5)

3、找到目标元素(输入框),输入要查询的快递单号,并点击查询

# 在目标页面的目标输入框中,自动填写单号并自动点击查询按钮
def set_postNo(postno):
    input_area = page.ele('t:div@@class=bill-number')
    input_area.ele('t:input@@type=text').input(postno)
    sleep(0.3)
    input_area.ele('t:button@@class=submit-button').click()
    sleep(1)

4、计算缺口位置


# 计算缺口图片与背景图的距离并移动
def compute_move_postion():
    # 等待页面加载完成,便于后续获取验证码(缺口)图片和背景图片
    page.wait.load_start()

    new_Iframe = page.ele('#tcaptcha_iframe')
    target_Img = new_Iframe.ele('#slideBlock')

    # print(f'目标图的坐标:{target_Img.location}')
    # print(f'目标图的尺寸:{target_Img.size}')

    # 下载缺口图片
    DownLoadImg(target_Img.attr('src'), "start_pos.jpg")
    target_Bg_Img = new_Iframe.ele('#slideBg')
    # print(f'背景图的坐标:{target_Bg_Img.location}')
    # print(f'背景图的尺寸:{target_Bg_Img.size}')
    # 下载背景图片
    DownLoadImg(target_Bg_Img.attr('src'), "end_pos.jpg")

    # 计算(两个图片在网页中坐标起点)差值
    chazhi = target_Img.location[0] - target_Bg_Img.location[0]
    print(chazhi)
    # data=computeDistance()
    # data=distance()

    data = identify_gap(r'start_pos.jpg', r'end_pos.jpg')
    print(data)
    # moveVal = data[0] - chazhi * 2
    # print(moveVal + 30)
    #
    # dealVerify(moveVal + 30)

    moveVal = data[0] - chazhi
    print(moveVal)

    dealVerify(moveVal)

部分代码解释:

new_Iframe = page.ele('#tcaptcha_iframe')
target_Img = new_Iframe.ele('#slideBlock')
找到滑块缺口图片和背景图片元素,便于将图片下载到本地

# 计算(两个图片在网页中坐标起点)差值

chazhi = target_Img.location[0] - target_Bg_Img.location[0]

5、计算缺口值


# 计算缺口坐标
def identify_gap(bg, cut):
    '''
    bg: 背景图片
    cut: 缺口图片
    '''
    # 读取背景图片和缺口图片
    bg_img = cv2.imread(bg)  # 背景图片
    cut_img = cv2.imread(cut)  # 缺口图片

    # 识别图片边缘
    bg_edge = cv2.Canny(bg_img, 100, 200)
    cut_edge = cv2.Canny(cut_img, 100, 200)

    # 转换图片格式
    bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
    cut_pic = cv2.cvtColor(cut_edge, cv2.COLOR_GRAY2RGB)

    # 缺口匹配
    res = cv2.matchTemplate(bg_pic, cut_pic, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配

    # 返回缺口坐标
    return max_loc

6、使用PyAutoGUI移动滑块

# 移动滑块
def dealVerify(move):
    drag_btn = pyautogui.locateOnScreen(r'./sf_img/start_postion.png', confidence=0.6, grayscale=True)
    if drag_btn is not None:

        pyautogui.moveTo(drag_btn, duration=1)

        pyautogui.dragRel(move, 0, duration=1, button='left')
    else:
        print('未识别到图标')

7、图片下载方法:

# 将网络图片下载到本地
def DownLoadImg(img_link, path):
    data = requests.get(img_link).content
    while True:
        time.sleep(0.2)
        if len(data) > 5:
            break
    with open(path, "wb") as f:
        f.write(data)

8、方法整体调用:


if __name__ == "__main__":
    # Win+D 返回桌面
    pyautogui.hotkey('winleft', 'd')
    # 打开谷歌浏览器
    page = ChromiumPage()
    # 在谷歌浏览器中打开目标网址
    openBrowserPage()

    postno = '要查询的快递单号XXXXXXXXXXXXXXXXXXXX'
    # 自动填写快递单号并检索
    set_postNo(postno)

    compute_move_postion()

通过上面的步骤,可以实现顺丰快递单号的自动查询,通过如果需要查询后的结果,可以使用DrissionPage 来获取查询的结果。

写在最后

上述的方法可以实现通过模拟人工的形式快递单号的自动查询,当然,仅仅用作技术研究。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coding行者

你的鼓励,将是我持续分享的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值