美文网首页
pyppeteer(五)--执行自定义js

pyppeteer(五)--执行自定义js

作者: 瓜T_T | 来源:发表于2019-06-28 14:30 被阅读0次

    直接上干货

    注入拦截和筛选请求和返回

    下面这个例子经常用来:

    • 加快网页加载速度
    • 快速筛选数据api接口

    做新闻爬虫的时候,遇到网页有视频其实挺尴尬的,首先如果加载视频会导致打开网页比较慢,有时甚至会导致浏览器超时崩溃,其次是视频的加载可能不同时带入一些广告的超链接,对于提取新闻内容会造成干扰。
    通过page.setRequestInterception参数开启注入。
    先上整体代码

    import asyncio
    from pyppeteer import launch
    
    async def inject_request(req):
        """
        resourceType:
            document, stylesheet, image, media, font, script, texttrack, 
            xhr, fetch, eventsource, websocket, manifest, other
        """
        if req.resourceType in ['media','image']:
            await req.abort()
        else:
            await req.continue_()
    
    async def inject_response(res):
    
        if res.request.resourceType in ['xhr']:
            print(res.request.url)
        
    async def main():
        browser = await launch({'headless':False})
        page = await browser.newPage()
        await page.setRequestInterception(True)
        page.on('request', inject_request)
        page.on('response',inject_response)
        await page.goto('https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0')
        await page.waitFor(5 * 1000)
        await browser.close()
    
    asyncio.get_event_loop().run_until_complete(main())
    

    先分析inject_request部分,

    async def inject_request(req):
        if req.resourceType in ['media','image']:
            await req.abort()
        else:
            await req.continue_()
    
    

    一般用得比较多的是一个属性两个方法,
    一个属性:
    resourceType,表示请求的资源类型,有document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other(加粗的是比较常用的资源类型)
    两个方法:
    abort(),跳过当前请求
    continue_(),继续当前请求
    上面代码段意思是,不请求图片和媒体资源。

    inject_response部分

    async def inject_response(res):
    
        if res.request.resourceType in ['xhr']:
            print(res.request.url)
    

    一般js动态加载的数据连接在xhr资源,所以我这里把网页请求的xhr资源都打印出来,如果这里没有数据连接,那就是在document里面了,比F12清晰一点。

    注入js

    以淘宝登陆验证码为例

    1.gif
    淘宝的验证码验证模块会检测浏览器环境,主要是检测window.navigator.webdriver参数,如果是浏览器直接打开,如下图:
    image.png
    如果是使用webdriver驱动打开(selenium,puppeteer,pyppeteer),这个参数如下图:
    image.png
    尝试直接覆盖这个属性,但是没有效果。
    image.png
    通过查资料,发现

    Object.defineProperty()
    方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。如果不指定configurable, writable, enumerable ,则这些属性默认值为false,如果不指定value, get, set,则这些属性默认值为undefined

    image.png

    完整代码

    import asyncio
    import random
    from pyppeteer import launch
    
    def input_time_random():
        return random.randint(100, 151)
    
    async def main():
        browser = await launch({'headless':False})
        page = await browser.newPage()
        await page.evaluateOnNewDocument(
            '''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } }) }''')
        await page.evaluateOnNewDocument('''() =>{ window.navigator.chrome = { runtime: {},  }; }''')
        await page.evaluateOnNewDocument('''() =>{ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] }); }''')
        await page.evaluateOnNewDocument('''() =>{ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }''')
        await page.goto('https://login.taobao.com')
        await page.waitFor(4 * 1000)
        await page.click('#J_QRCodeLogin > div.login-links > a.forget-pwd.J_Quick2Static')
        await page.waitFor(3 * 1000)
        await page.type('#TPL_username_1', '123123', {'delay': input_time_random() - 50})
        await page.type('#TPL_password_1', '232322332', {'delay': input_time_random()})
        await page.waitFor(2 * 1000)
        el = await page.querySelector('#nc_1_n1z')
        box = await el.boundingBox()
        await page.hover('#nc_1_n1z')
        await page.mouse.down()
        await page.mouse.move(box['x']+1000,box['y'], {'delay': random.randint(1000, 2000),'steps':3})
        await page.mouse.up()
        await page.waitFor(5 * 1000)
        await browser.close()
    
    asyncio.get_event_loop().run_until_complete(main())
    
    1.gif

    相关文章

      网友评论

          本文标题:pyppeteer(五)--执行自定义js

          本文链接:https://www.haomeiwen.com/subject/ubxjqctx.html