web自动化 -- pyppeteer

由于Selenium流行已久,现在稍微有点反爬的网站都会对selenium和webdriver进行识别,网站只需要在前端js添加一下判断脚本,很容易就可以判断出是真人访问还是webdriver。虽然也可以通过中间代理的方式进行js注入屏蔽webdriver检测,但是webdriver对浏览器的模拟操作(输入、点击等等)都会留下webdriver的标记,同样会被识别出来,要绕过这种检测,只有重新编译webdriver,麻烦自不必说,难度不是一般大。

 pyppeteer简介

由于Selenium具有这些严重的缺点。pyperteer成为了爬虫界的又一新星。

相比于selenium具有以下特点:

异步加载

速度快

具备有界面/无界面模式

伪装性更强不易被识别为机器人

同时可以伪装手机平板等终端

------------------->>>>

虽然支持的浏览器比较单一,但在安装配置的便利性和运行效率方面都要远胜selenium。

pyppeteer无疑为防爬墙撕开了一道大口子,针对selenium的淘宝、美团、文书网等网站,目前可通过该库使用selenium的思路继续突破,毫不费劲。

Pyppeteer是一个基于Python的浏览器自动化库,它使用了Puppeteer(谷歌开发的Node.js工具)的思路,通过JavaScript代码操纵Chrome浏览器完成数据爬取和Web程序自动测试等任务。Pyppeteer使用Python异步协程库asyncio,可以整合Scrapy进行分布式爬虫。

在Pyppeteer中,实际上背后有一个类似Chrome浏览器的Chromium浏览器在执行一些动作进行网页渲染。Chromium是谷歌为了研发Chrome而启动的项目,是完全开源的。二者基于相同的源代码构建,功能上基本没有太大区别。

web自动化 -- pyppeteer_第1张图片

总之,Pyppeteer依赖于Chromium这个浏览器来运行的。

pyppeteer安装及配置

由于 Pyppeteer 采用了 Python 的 async 机制,所以其运行要求的 Python 版本为 3.5 及以上。

第一步:在python中安装pyppeteer第三库

安装方式很简单,命令行 pip 安装即可。

pip3 install pyppeteer

或者直接在IDE中进行安装:

web自动化 -- pyppeteer_第2张图片

 第二步:输入以下两行代码

import pyppeteer
print(pyppeteer.chromium_downloader.chromiumExecutable)

记住打印结果中圈出的数字,这是chromium的borwser驱动版本号

web自动化 -- pyppeteer_第3张图片 第三步:去下载对应版本的chromium的borwser

在这里使用的是淘宝镜像中的chromium
进入这个网址:CNPM Binaries Mirror

web自动化 -- pyppeteer_第4张图片

选择对应系统和对应的版本(我这里是windows系统,选择了我系统默认的588429) 

web自动化 -- pyppeteer_第5张图片

第四步:borwser驱动下载之后,将文件解压,放入上面pycharam中指定的路径中

也就是‘C:/Users/xiaohuamiao/AppData/Local/pyppeteer/pyppeteer/local-chromium/588429/chrome-win32/chrome.exe’这个路径;

需要手动在/pyppeteer/pyppeteer/文件下新建‘local-chromium’的文件夹、再新建'588429'的文件夹,然后将解压的文件'chrome-win32'放在‘588429’这个文件下

web自动化 -- pyppeteer_第6张图片

第五步:在python的库管理文件夹site-packages中pyppeteer文件:

web自动化 -- pyppeteer_第7张图片

进入chromium_downloader.py文件并打开修改代码:

web自动化 -- pyppeteer_第8张图片

这里是什么系统的就改什么后面的,我是windows,所以改windows的;

还有要注意,一定是要把https改成http,不然会报ssl的错 

#修改后代码:
downloadURLs = {
    'linux': f'{BASE_URL}/Linux_x64/{REVISION}/chrome-linux.zip',
    'windows': f'http://cdn.npm.taobao.org/dist/chromium-browser-snapshots/Mac/588429/chrome-win32.zip',
    'win32': f'{BASE_URL}/Win/{REVISION}/{windowsArchive}.zip',
    'win64': f'{BASE_URL}/Win_x64/{REVISION}/{windowsArchive}.zip',
}

第六步:在pycharm中执行安装:

import pyppeteer.chromium_downloader
pyppeteer.chromium_downloader.download_chromium()

等待安装、显示安装100%即可

web自动化 -- pyppeteer_第9张图片

验证一下,是否安装成功:在cmd中再次pyppeteer-install,出现以下提示,说明安装成功:

web自动化 -- pyppeteer_第10张图片


pyppeteer的使用

pyppeteer的用法与Selenium基本一致,这里就不再一一介绍了

滑动验证登陆demo

在上一篇Selenium的滑动验证登陆demo中,web自动化 -- selenium及应用-CSDN博客

使用opencv简单快捷实现了计算缺口图片在背景图中的距离,但是由于没有进行拟人化处理,导致太快滑动对接上,从而被京东识别到是爬虫程序,呗拦截了,这里继续使用pyppeteer,以及做一下拟人化处理,进行完整的滑动验证到登陆:

完整代码如下:

import random
from pyppeteer import launch
import asyncio
import cv2
from urllib import request


async def get_track():
    background = cv2.imread("background.png", 0)
    gap = cv2.imread("gap.png", 0)

    res = cv2.matchTemplate(background, gap, cv2.TM_CCOEFF_NORMED)
    value = cv2.minMaxLoc(res)[2][0]
    print(value)
    return value * 242 / 360


async def main():
    browser = await launch({
        "headless": False,  # headless指定浏览器是否以无头模式运行,默认是True。
        "args": ['--window-size=1366,768'],
    })
    # 打开新的标签页
    page = await browser.newPage()
    # 设置页面大小一致
    await page.setViewport({"width": 1366, "height": 768})
    # 访问主页
    await page.goto('https://passport.jd.com/new/login.aspx?')

    # evaluate()是执行js的方法,js逆向时如果需要在浏览器环境下执行js代码的话可以利用这个方法
    # js为设置webdriver的值,防止网站检测
    # await page.evaluate('''alert("马上输入用户名密码了!")''')
    # await page.evaluate('''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } }) }''')
    # await page.screenshot({'path': './1.jpg'})   # 截图保存路径

    # 模拟输入用户名和密码,输入每个字符的间隔时间delay ms
    await page.type("#loginname", '[email protected]', {
        "c": random.randint(30, 60)
    })
    await page.type("#nloginpwd", '345653332', {
        "delay": random.randint(30, 60)
    })

    # page.waitFor 通用等待方式,如果是数字,则表示等待具体时间(毫秒): 等待2秒
    await page.waitFor(2000)
    await page.click("div.login-btn")
    await page.waitFor(2000)
    # page.jeval(selector,pageFunction)#定位元素,并调用js函数去执行
    img_src = await page.Jeval(".JDJRV-bigimg > img", "el=>el.src")
    temp_src = await page.Jeval(".JDJRV-smallimg > img", "el=>el.src")

    request.urlretrieve(img_src, "background.png")
    request.urlretrieve(temp_src, "gap.png")

    # 获取gap的距离
    distance = await get_track()
    """
        # Pyppeteer 三种解析方式
        Page.querySelector()  # 选择器
        Page.querySelectorAll()
        Page.xpath()  # xpath  表达式
        # 简写方式为:
        Page.J(), Page.JJ(), and Page.Jx()
        """
    el = await page.J("div.JDJRV-slide-btn")
    # 获取元素的边界框,包含x,y坐标
    box = await el.boundingBox()
    await page.hover("div.JDJRV-slide-btn")
    await page.mouse.down()
    # steps 是指分成几步来完成,steps越大,滑动速度越慢
    await page.mouse.move(box["x"] + distance + random.uniform(30, 33), box["y"], {"steps": 100})
    await page.waitFor(1000)
    await page.mouse.move(box["x"] + distance + 29, box["y"], {"steps": 100})
    await page.mouse.up()
    await page.waitFor(2000)

    await asyncio.sleep(3600)

if __name__ == '__main__':
    asyncio.run(main())

代码执行后,如下:

因为我输入的账号和密码都是错误的,所以滑块验证成功之后,得到响应提示账号密码不匹配

说明登陆已经发送成功了

web自动化 -- pyppeteer_第11张图片

你可能感兴趣的:(python爬虫,软件测试,自动化)