pyppeteer(七)--网易拖拉验证码

首先需要打开浏览器两个target,tagget[0]用来正常加载目标网页,target[1]用来准备加载验证码图片

await browser.newPage() # 新增一个tab用作验证码截图,一起截的话两个图片会重叠在一起
pages = await browser.pages() # 获取所有page,page[0]正常浏览page[1]用作加载图片
await pages[0].setViewport({'width': 1024, 'height': 768})
await pages[0].goto('http://dun.163.com/trial/jigsaw',{'waitUntil':'domcontentloaded'})
image.png

下载验证码图片,主要逻辑是下面这个函数,先获得图片的url,然后用target1打开,再通过元素级截图把验证码截下来。

async def get_img(pages,img_str,img_path):
    
    img_url = await pages[0].evaluate(img_str)
    await pages[1].goto(img_url)
    img = await pages[1].waitForSelector('body > img')
    await img.screenshot({'path':img_path})

获取图片后是计算距离,计算距离的核心是教程(六)的算法

async def calc_distance(bg_img,flag_img):
    gray = cv2.imread(bg_img,0)
    flag = cv2.imread(flag_img,0)
    w,h = flag.shape[::-1]
    res = cv2.matchTemplate(gray,flag,cv2.TM_CCOEFF_NORMED)
    L = 0
    R = 1
    while 1:
        threshold = (L+R)/2
        loc = np.where(res >= threshold)
        if len(loc[0]) > 1:
            L += (R-L) /2
        elif len(loc[0]) == 1:
            pt = loc[::-1]
            break
        elif len(loc[0]) < 1:
            R -= (R-L) / 2
    return pt[0][0]

计算后的距离需要等比例放大,真实距离=计算距离*页面元素框长度/图片宽度
t_distance = round(distance*318/320)
通过
await pages[0].bringToFront()告诉浏览器页面标签0前置
然后是开始拖动滑块操作

async def slide(pages,distance):
    el = await pages[0].querySelector('div.yidun_slider')
    box = await el.boundingBox() # 一定要先用选择器再取box函数,串联起来不行
    await pages[0].waitFor(2 * 1000)
    await pages[0].hover('div.yidun_slider')
    await pages[0].waitFor(2 * 1000)
    await pages[0].mouse.down()
    await pages[0].mouse.move(box['x']+distance+20+9,box['y'],{'steps':3})
    await pages[0].mouse.up()

获取滑块坐标,然后滑动距离,这里await pages[0].mouse.move(box['x']+distance+20+9,box['y'],{'steps':3})的20+9是滑块的宽度一半在加一个测试后比较稳定的偏差值。
剩下的部分是验证是否滑动成功,如果不成功则重新滑动。

async def check(pages,BG_IMG_STR, FLAG_IMG_STR, BG_IMG_PATH, FLAG_IMG_PATH):
    while 1:
        await pages[0].waitFor(1 * 1000)
        success_msg = await pages[0].querySelector('div.yidun.yidun--light.yidun--float.yidun--jigsaw.yidun--success')
        # error_msg = await pages[0].querySelector('div.m-form-group.login-error > p > span')
        if not success_msg:
            await drag(pages, BG_IMG_STR, FLAG_IMG_STR, BG_IMG_PATH, FLAG_IMG_PATH)
        else:
            print("success")
            break

你可能感兴趣的:(pyppeteer(七)--网易拖拉验证码)