Python爬虫之pyppeteer的使用(爬虫、获取cookie、截屏插件、防爬绕过)

拦截请求

可以对出现的请求,进行拦截 类似mitmproxy。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
@time:2020/04/04
"""
 
import asyncio
import json
 
from jsonpath import jsonpath
from pyppeteer import launcher
 
launcher.AUTOMATION_ARGS.remove("--enable-automation")
 
from pyppeteer import launch
 
from pyppeteer.network_manager import Request, Response
 
 
async def intercept_request(req:Request):
    await req.continue_()  # 请求,看源码可以重新编写请求
 
 
async def intercept_response(res:Response):
    if 'ext2020/apub/json/prevent.new' in res.url:
        print('拦截到请求')
        json_text = await res.text()
        title_li = jsonpath(json.loads(json_text), '$..title')
        for title in title_li:
            print(title)
    pass
 
 
async def main():
    # 浏览器 启动参数
    start_parm = {
        # 启动chrome的路径
        "executablePath": r"C:\Users\yq\AppData\Local\pyppeteer\pyppeteer\local-chromium\722234\chrome-win\chrome.exe",
        # 关闭无头浏览器 默认是无头启动的
        "headless": False,
        "args": [
            '--disable-infobars',  # 关闭自动化提示框
            # '--no-sandbox',  # 关闭沙盒模式
            '--start-maximized',  # 窗口最大化模式
            '--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',
            # UA
 
        ],
 
    }
    # 创建浏览器对象,可以传入 字典形式参数
    browser = await launch(**start_parm)
 
    # 创建一个页面对象, 页面操作在该对象上执行
    page = await browser.newPage()
    await page.setJavaScriptEnabled(enabled=True)
 
    # 启用拦截器
    await page.setRequestInterception(True)
    page.on('request', intercept_request) 
    page.on('response', intercept_response)
    
    js_text = """
    () =>{ 
        Object.defineProperties(navigator,{ webdriver:{ get: () => false } });
        window.navigator.chrome = { runtime: {},  };
        Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] });
        Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], });
     }
        """
    await page.evaluateOnNewDocument(js_text)  # 本页刷新后值不变,自动执行js
    await page.goto('https://news.qq.com/')  # 页面跳转
 
 
    await browser.close()
 
 
asyncio.get_event_loop().run_until_complete(main())   # 创建异步池并执行main函数。


验证码识别和输入

我在这里利用了某网站的验证码识别api,通过http方式就能上传验证码图片,并获取验证码。这个网站每天有固定的1000张图片免费次数,足够我们使用。第一个请求链接的用户名和密码换成我们注册该网站的用户名和密码即可。具体可以看官方的API文档。
该网站地址:http://fast.95man.com/

# 验证码登录
    async def verification_code(self, page):
        await page.waitFor(5 * 1000)                                     # 等待验证码图片加载
        yazhengma = await page.waitForSelector('#captchaImg')            # 定位验证码元素
        await yazhengma.screenshot({'path': './picture/yazhengma.png'})  # 保存验证码图片
 
        # 获取验证码
        code = self.get_code('./picture/yazhengma.png')
 
        # 输入验证码
        await page.type('#captchaResponse', code, {'delay': self.input_time_random()})
 
    def get_code(self, file_path):
            # 以下为GET请求
            url = 'http://api.95man.com:8888/api/Http/UserTaken?user=username&pwd=password&isref=0'
            token_request = requests.get(url)
            token_raw = str(token_request.content)
 
            # 切片获取token
            token = token_raw[4: -1]
 
            print(token)
 
            # 发送图片解析请求
            url = "http://api.95man.com:8888/api/Http/Recog?Taken=" + token + "&imgtype=1&len=4"
            file_path = file_path
            files = {'file': open(file_path, 'rb')}
 
            # 上传图片
            r = requests.post(url, files=files)
            print(r.url, r.text)
 
            # 切片获取验证码
            return r.text[6:10]

防检测的一些方法

async def init_pyppeteer(self):
        self.browser = await pyppeteer.launch({'headless': False,
                                               # 'userDataDir': './userdata',# 用户临时目录,保存cookie可以开启
                                               'args': [
                                                   # '--window-size={1300},{800}',
                                                   '--start-maximized',  # 最大化窗口
                                                   '--proxy-server=http://118.24.51.247:1443',#浏览器代理 配合某些中间人代理使用
                                                   # '--load-extension={}'.format(chrome_extension),  # 加载插件
                                                   # '--disable-extensions-except={}'.format(chrome_extension),
                                                   # '--disable-extensions',
                                                   '--hide-scrollbars',
                                                   '--disable-bundled-ppapi-flash',
                                                   '--mute-audio',
                                                   '--no-sandbox',  # 取消沙盒模式 沙盒模式下权限太小
                                                   '--no-sandbox',  # 不显示信息栏  比如 chrome正在受到自动测试软件的控制
                                                   '--disable-setuid-sandbox',
                                                   '--disable-gpu',
                                                   '--disable-infobars'
                                                   # log等级设置 在某些不是那么完整的系统里 如果使用默认的日志等级 可能会出现一大堆的warning信息
                                               ],
                                               'dumpio': True,  # 减少内存消耗
                                               # "slowMo": 25  # 让执行慢下来
                                               })
        self.page = await self.browser.newPage()
        width, height = self.screen_size()
        await self.page.setViewport({
            "width": width,
            "height": height
        })
        # 设置浏览器头部
        await self.page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                                     '(KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299')
        await self.page.evaluateOnNewDocument('() =>{ Object.defineProperties(navigator,'
                                         '{ webdriver:{ get: () => false } }) }')  # 本页刷新后值不变

1.1、绕过对方网站监测

import pyppeteer
async def page_evaluate(self, page):
    '''window.navigator.webdriver=false'''
    await page.evaluate('''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => undefined } }) }''')  # 以下为插入中间js,将淘宝会为了检测浏览器而调用的js修改其结果。
    await page.evaluate('''() =>{ window.navigator.chrome = { runtime: {},  }; }''')
    await page.evaluate('''() =>{ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] }); }''')
    await page.evaluate('''() =>{ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }''')
 
async def main(self):
    browser = await pyppeteer.launch()
    page = await browser.newPage()
    await self.page_evaluate(page)

Python 2020-10-07 17:50:28 通过 网页 浏览(182)

共有0条评论!

发表评论