自动化采集数据之解决滑动验证码

# 对于初级选手和数据需求不大的的数据采集,使用自动化库进行模拟,但是抵不住请求多了还是会蹦验证,所以具备处理验证的能力也是十分有必要的。

一、工具准备

python的自动化工具主要有Selenium和DrissionPage。

(一)Selenium

Selenium的核心功能是在多个浏览器上进行自动化测试,帮助测试人员减少手动测试的工作量。
Selenium的发展历程可以追溯到2004年,当时‌ThoughtWorks公司的一个员工Jason Huggins为了减少手工测试的工作量,开发了一套JavaScript库,这套库后来发展成为Selenium Core,为Selenium Remote Control(RC)和Selenium IDE提供了坚实的基础。Selenium 1.x时期主要使用Selenium RC进行自动化测试。随着技术的发展,Selenium逐渐演变为一个功能强大的自动化测试工具,被包括‌Google、‌百度、‌腾讯等公司在内的许多大型企业广泛使用。

(二)DrissionPage

DrissionPage是一个基于 python 的网页自动化工具。它既能控制浏览器,也能收发数据包,还能把两者合而为一。可兼顾浏览器自动化的便利性和 requests 的高效率。它功能强大,内置无数人性化设计和便捷功能。它的语法简洁而优雅,代码量少,对新手友好。

所以面向大多数的新手朋友,我们选择DrissionPage。

二、逻辑准备

拼图是在水平方向上的滑动,我们需要的就是得到缺口的位置和初始的位置,得到它们的差值,然后把拖动按钮,拖动的距离就是根据前面提到的差值。

首先,为了得到图片我们可以利用xpath,如果图片网址是固定的或者是一个img的src,可以用src()等直接得到,如果是随机的,那就用截图的方式(Selenium的话2只能截图)。

得到两张图后,利用ddddocr,可以在原图(背景图)上得到一组坐标,左上角和右下角。

ocr = ddddocr.DdddOcr(det=False, ocr=False)  # 禁用文字识别
background = "1.png"
with open(background, 'rb') as f:
    background_img = f.read()
front = "2.png"
with open(front, 'rb') as f:
    front_img = f.read()
# 调用 ddddocr 的滑块匹配功能
res = ocr.slide_match(background_img, front_img, simple_target=True)
target = res['target']

三、代码实现

以shunfeng订单查询为例。

from DrissionPage import ChromiumPage
import time
import ddddocr
import cv2
import matplotlib.pyplot as plt
import requests


def show_with_matplotlib(imgPath, location):
    img = cv2.imread(imgPath)
    # 绘制红色矩形框
    cv2.rectangle(
        img,
        (location[0], location[1]),
        (location[2], location[3]),
        (0, 0, 255),
        2
    )
    # 将 BGR 转换为 RGB
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # 使用 Matplotlib 显示图像
    plt.imshow(img_rgb)
    plt.axis('off')  # 关闭坐标轴
    plt.show()


def downloadImage(url, fileNme):
    r = requests.get(url)
    with open(fileNme, 'wb') as f:
        f.write(r.content)


def getLocation(Page):
    time.sleep(5)
    img1Url = Page.ele('x:/html/body/div[7]/div[1]/div[1]/div[2]/div/div/div[1]/div[2]').style(
        'background-image').replace('url(', '').replace(')', '').replace('"', '')
    downloadImage(img1Url, '1.png')
    img2Url = Page.ele('x:/html/body/div[7]/div[1]/div[1]/div[2]/div/div/div[1]/div[1]/div[1]').style(
        'background-image').replace('url(', '').replace(')', '').replace('"', '')
    downloadImage(img2Url, '2.png')
    locations = Page.ele('x:/html/body/div[7]/div[1]/div[1]/div[2]/div/div/div[2]/div').rect.corners[0:4:3]
    location = (int(locations[0][0]), int((locations[0][1] + locations[1][1]) / 2))
    return location


def detect():
    ocr = ddddocr.DdddOcr(det=False, ocr=False)  # 禁用文字识别
    background = "1.png"
    with open(background, 'rb') as f:
        background_img = f.read()
    front = "2.png"
    with open(front, 'rb') as f:
        front_img = f.read()
    # 调用 ddddocr 的滑块匹配功能
    res = ocr.slide_match(background_img, front_img, simple_target=True)
    target = res['target']
    show_with_matplotlib(background, target)
    return target[0]


def mover(Page, target):
    Page.ele('x:/html/body/div[7]/div[1]/div[1]/div[2]/div/div/div[2]/div/div[3]').drag_to(target)
    time.sleep(55)
    pass


if __name__ == '__main__':
    page = ChromiumPage()
    page.get("https://www.sf-express.com/chn/sc/waybill/waybill-detail/SF3109285694508")
    loc = getLocation(page)
    addX = detect()
    X = (loc[0] + addX + 40, loc[1])
    mover(page, X)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值