Playwright 自动化操作

之前有见同事用过playwright进行浏览器模拟操作,但是没有仔细了解,今天去详细看了下,发现playwright着实比selenium牛逼多了

  • Playwright 相对于selenium优点
    1、自动下载chromnium, 无需担心chrome升级对应版本问题
    2、支持录屏操作,然后直接生成python代码;
    3、支持网路拦截、事件监听,纵使我们是模拟浏览器,但是依旧可以在request请求上作文章,这个就很牛逼;
    4、代码简洁性更高;
    5、支持异步处理;

  • 安装使用

    #下载第三方库
    pip3 install playwright
    #安装好后,进行初始化操作,它会自动安装chromium, Firefox , webkit浏览器并配置一些驱动
    playwright install
    
  • 录屏操作
    1、使用控制台(terminal,cmd, powershell),进入到项目目录下;
    2、查看所有的录屏相关命令:playwright codegen -h
    3、启动示例:

    #-o 非必须,输出代码到指定文件,如果不指定,也可以在界面中复制代码就好
    #-b 非必须,指定浏览器, 默认是chromnium
    #--device #非必须, 指定机器型号
    #www.baidu.com #非必须, 指定访问的url
    playwright codegen -o luping.py -b chromnium --device="iphone 13" www.baidu.com
    
    #--save-storage 保存浏览器缓存,可以自定义指定项目名称
    playwright codegen -b cr  --save-storage=saiying www.saleyee.cn
    #--load-storage 获取已有的浏览器缓存,指定好项目名称就好
    playwright codegen -b cr  --load-storage=saiying www.saleyee.cn
    

    4、录屏时,直接人工操作就好了,也可以暂停录屏,至于如何获取元素内容,需要自己探究;
    5、退出录屏,只要在控制台ctrl+C
    在这里插入图片描述
    6、然后把代码改一改,就可以使用了,这个还是很方便的;

    • 使用代码示例
      事件监听:
    • "close":页面关闭事件。
    • "console":页面上发生控制台日志事件。
    • "crash":页面崩溃事件。
    • "dialog":页面弹出对话框事件。
    • "domcontentloaded":DOM 内容加载完成事件。
    • "download":页面上触发下载事件。
    • "filechooser":页面弹出文件选择对话框事件。
    • "frameattached":子框架附加到页面事件。
    • "framedetached":子框架从页面分离事件。
    • "framenavigated":子框架导航事件。
    • "load":页面加载完成事件。
    • "pageerror":页面上发生错误事件。
    • "popup":页面弹出弹出窗口事件。
    • "request":页面发出网络请求事件。
    • "requestfailed":页面上的请求失败事件。
    • "requestfinished":页面上的请求完成事件。
    • "response":页面接收到网络响应事件。
    • "websocket":页面上发生 WebSocket 事件。
    • "worker":页面上发生 Worker 事件。
# -*- coding: utf-8 -*-
import asyncio
import time
from urllib import parse
from playwright.async_api import async_playwright
from playwright.sync_api import sync_playwright




#!!!!!!!!!!!!!!响应事件response监听, 数据采集的逻辑可以在这里做
def on_response(response):
    if 'api/movie/' in response.url and response.status == 200:
        # print(f'Statue {response.status}: {response.url}')
        print(response.json())

#请求事件request监听,只能获取相关的请求参数,用处不大,
def on_request(request):
    print(request.url)

#!!!下载事件监听,比如店铺后台的表格下载就可以在此处理
def on_download(download):
    print(f"Download started: {download.url}")

#!!!!!!!!!!!!!网络劫持
#可以实现网络劫持和修改操作,比如非加密,通过相应参数修改,获取自定义返回的内容,从而采集
#它就相当于一个网络钩子,可以修改请求信息, 还可以设置保持浏览器上url不变的情况下,跳转其他站点页面
def handle_request(route, request):
    url = request.url
    if url == "http://example.com":
        if route.request.method == "GET":
            print(f"GET请求url为:{route.request.url}")
            bits = list(parse.urlparse(url))
            qs = parse.parse_qs(bits[4])
            qs["key1"] = ["GET"]  # 此处替换key1的值
            bits[4] = parse.urlencode(qs, True)
            url = parse.urlunparse(bits)
            print(f"改变后的url为: {url}\n")
            route.continue_(url=url)
        elif route.request.method == "POST":
            print(f"POST请求入参为:{route.request.post_data}")
            text_list = route.request.post_data.split("&")
            for i in range(len(text_list)):
                text_item = text_list[i]
                if "key1=" in text_item:
                    text_list[i] = "key1=POST"  # 此处替换key1的值
            print(f"改变后的数据为: {'&'.join(text_list)}\n")
            route.continue_(post_data="&".join(text_list))

# 同步
# 使用with打开服务可以避免中间代码执行报错导致无法正常关闭浏览器进程
with sync_playwright() as p:
    # browser_type_list = [p.chromium, p.firefox, p.webkit]
    for browser_type in [p.chromium]:
        browser = browser_type.launch(headless=False)

        #=======!!!可以指定项目名称,例(saiying),这样可以继承上一次浏览器缓存,这样可以规避下重复登录的问题, 但是不清楚没有该项目名称情况下会有什么问题
        # 也可以不指定创建一个新的context = browser.new_context()
        # 如果使用该种方式,记得流程结束后,要再保留下当前缓存context.storage_state(path="saiying"), 在下面有示例
        # context = browser.new_context(storage_state="saiying")
        # page = context.new_page()



        #直接生成新浏览器执行对象
        page = browser.new_page()

        #事件监听----start
        page.on('response', on_response)    #响应事件监听
        page.on('request', on_request)      #发起请求事件监听
        page.on('download', on_download)  # 文件下载事件监听
        # 事件监听----end

        #网络拦截---start
        route_url = 'http://127.0.0.1/zentao/testcase-create-1-0-0.html' #可以指定拦截url,或者部分定制url
        #route_url = '**'       #指定全部的url
        #route_url = '**/*.json'    #指定部分url
        page.route(route_url, handle_request)  # 监听添加用例接口
        # 网络拦截---end

        page.goto('https://spa6.scrape.center/') #请求网页地址
        page.wait_for_load_state('networkidle') #等待页面所有请求响应完毕,还有load, domcontentloaded


        element = page.query_selector('xpath=//a')  #单节点定位
        elements = page.query_selector_all('xpath=//a')  # 多节点定位
        for element in elements:
            print(element.inner_html())         #打印该节点下所有标签内容
            print(element.get_attribute('href'))
            element.query_selector('xpath=.//img')
        print(page.title())

        #=======!!! 在登录完毕,或者操做完毕后,保留当前缓存,供下次调用
        # context.storage_state(path="saiying")
        # context.close()

        page.close()
        browser.close()         #关闭浏览器


# #异步, 感觉用处不大
# async def main():
#     async with async_playwright() as p:
#         # browser_type_list = [p.chromium, p.firefox, p.webkit]
#         for browser_type in [p.chromium]:
#             browser = await browser_type.launch(headless=False)
#             page = await browser.new_page()
#             await page.goto('https://www.baidu.com')
#             print(await page.title())
#             await browser.close()
#
# asyncio.run(main())
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值