python使用opencv和pyautogui库,模拟手动过滑动验证实现在试卷网批量下载试卷

 不会爬虫,只会用这种笨办法

import pyautogui
import time
import cv2
import numpy as np

#缺口图位置检测,缺口相对背景图片边缘的位置
def 缺口图位置检测(tp_img, bg_img):
    '''
    bg: 背景图片
    tp: 缺口图片
    '''
    # 识别图片边缘
    bg_edge = cv2.Canny(bg_img, 100, 200)
    tp_edge = cv2.Canny(tp_img, 100, 200)

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

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

    # 绘制方框
    th, tw = tp_pic.shape[:2]
    tl = max_loc  # 左上角点的坐标
    br = (tl[0] + tw, tl[1] + th)  # 右下角点的坐标
    cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2)  # 绘制矩形
    #cv2.imwrite('112.jpg', bg_img)  # 保存在本地

    # 返回缺口的X坐标
    return tl[0]

def 截取背景图(bg_img_x, bg_img_y, bg_img_width, bg_img_high): #分别代表:左上角坐标,宽高
    #在屏幕指定区域截屏 作为背景图片
    bg_img = pyautogui.screenshot(region=[bg_img_x, bg_img_y, bg_img_width, bg_img_high])  #分别代表:左上角坐标,宽高

    # 对获取的图片转换成二维矩阵形式,后再将RGB转成BGR
    # 因为imshow,默认通道顺序是BGR,而pyautogui默认是RGB所以要转换一下,不然会有点问题
    bg_img = cv2.cvtColor(np.asarray(bg_img), cv2.COLOR_RGB2BGR)
    return bg_img

def identify(tp_img):
    背景图 = 截取背景图(1160, 590, 280, 210) # 分别代表:左上角坐标,宽高
    out = 缺口图位置检测(tp_img, 背景图)
    print(out)

    #out<50认为检测错误,退出循环
    if out<50:
        return 0
    # 鼠标移动到滑动按钮
    pyautogui.moveTo(1130, 850)
    '''
    模拟人先滑过缺口,再滑回来的动作
    tween=pyautogui.easeInQuad      开始很慢,不断加速
    tween=pyautogui.easeOutQuad     开始很快,不断减速
    '''
    移动距离 = out + 30 + 40
    pyautogui.mouseDown()
    if out<100:
        pyautogui.moveTo(1130+移动距离-5, 850, duration=0.5,tween=pyautogui.easeInQuad)
    else:
        pyautogui.moveTo(1130 + 移动距离 - 5, 850, duration=0.8, tween=pyautogui.easeInQuad)
    pyautogui.moveTo(1130+移动距离, 850, duration=0.5, tween=pyautogui.easeOutQuad)
    pyautogui.mouseUp()

    time.sleep(5)#=等待网页自动下载

    #检测是否下载成功。
    背景图 = 截取背景图(1160, 590, 280, 210)
    out = 缺口图位置检测(tp_img, 背景图)

    #因为成功后的页码是固定的。预先可获得成功页码检测的返回值为128
    # ====如果识别失败,刷新验证框  坐标 1155,931
    if 128 == out:
        return 1
    else:
        return 0

试卷总数 = 20
网址 = "https://*****""%d"


下载页数 = (试卷总数+9) // 10
下载偏移 = 0
缺口图片 = cv2.imread('1.jpg')  # 缺口图片

#====起始位置====
pyautogui.moveTo(1815, 905)
pyautogui.scroll(2000)

for i in range(下载页数):
    当前页数 = i+1
    每页试卷数量 = 10

    #计算最后一页数量
    if (当前页数 == 下载页数) and (试卷总数%10 > 0):
        每页试卷数量 = 试卷总数%10

    print('第%d页 %d份试卷' % (当前页数, 每页试卷数量))

    for j in range(每页试卷数量):
        print('下载试卷%d'%j)
        '''
        pyautogui.moveTo(1820, 1128)  # =阶段测试的下载坐标
        '''
        while 1:
            #====点击下载
            pyautogui.click(1820, 1128)  #=阶段测试的下载坐标

            # ====点击确定下载,会弹出验证框
            time.sleep(1.5)  # ==等待确定下载按钮加载
            pyautogui.click(1278, 953)

            # ====识别验证框并拖动
            time.sleep(2)  # =等待识别页码加载
            ret = identify(缺口图片)

            # ====刷新页面退出下载
            pyautogui.click(128, 78)
            if ret == 1:
                break
            else:
                # 等待页面加载
                time.sleep(1)
            # ====关闭验证
            # time.sleep(1)
            # pyautogui.click(1114, 939)
        #====滚动页面
        time.sleep(1)
        pyautogui.moveTo(1820, 1128)
        time.sleep(0.5)
        pyautogui.scroll(-135)
        time.sleep(1)

    # ====滑到最上,然后在浏览器地址栏输入url,切换到下一页
    pyautogui.scroll(2000)
    pyautogui.click(400, 80)
    当前页数 = 当前页数 + 下载偏移 + 1
    pyautogui.typewrite(message=网址 % 当前页数, interval=0)
    pyautogui.press('enter')
    pyautogui.press('enter')

    # ====等待页码刷新
    time.sleep(1)

 

你可能感兴趣的:(opencv,python)