0


Playwright 入门详细教程

playwright的python文档

Playwright爬虫

安装

pip install playwright

# 安装驱动, 支持的浏览器:cr, chromium, ff, firefox, wk 和 webkit
playwright install

控制台启动录制

playwright codegen [options][url]
  • -o, --output :保存生成脚本
  • –target :生成的脚本语言,可以设置javascript, test, python, python-async和csharp,默认为python
  • -b, --browser :要使用的浏览器,可以选择cr, chromium, ff, firefox, wk和webkit,默认chromium。
  • –channel :chromium版本,比如chrome, chrome-beta, msedge-dev等
  • –color-scheme :模拟器的颜色主题,可选择light 或者 dark样式
  • –device :模拟的设备
  • –save-storage :保存上下文状态,用于保存cookies 和localStorage,可用它来实现重用。例如playwright codegen --save-storage=auth.json
  • –load-storage :加载–save-storage 保存的数据,重用认证数据。
  • –proxy-server :指定代理服务器
  • –timezone : 指定时区
  • –geolocation :指定地理位置坐标
  • –lang :指定语言/地区,比如中国大陆:zh-CN
  • –timeout :超时时间,定位毫秒,默认10000ms
  • –user-agent :用户代理
  • –viewport-size :浏览器窗口大小
  • -h, --help :查看帮助信息

例如:

playwright codegen -o test_playwright.py --target python  -b chromium --device="iPhone 12 Pro" https://www.baidu.com/

playwright open https://www.baidu.com/ # 默认使用Chromium打开
playwright wk https://www.baidu.com/ # 使用WebKit打开
playwright open--device="iPhone 12 Pro" https://www.baidu.com/ # 使用iPhone 12 Pro模拟器打开

基本用法

常见配置参数

headless,slow_mo,viewport,locale,timezone,color_scheme,geolocation,user_agent, timeout, proxy

同步模式

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    # 创建一个浏览器实例; headless:是否无头;slow_mo放慢执行速度# pixel_2 = playwright.devices['Pixel 2']  # Pixel 2 一款安卓手机
    proxy_ip ={'server':'http://',
            'username':'',
            'password':'',
        }
    browser = p.chromium.launch(headless=False, slow_mo=100, proxy=proxy_ip)
    context = browser.new_context(viewport={'width':1800, 'height':800},    # 窗口大小locale='zh-CN',  #语言zh-CN/en-ENtimezone='Europe/Rome',   #时区color_scheme='dark',    # 颜色geolocation={"longitude":48.858455, "latitude":2.294474}# 地理位置user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', # 浏览器,timeout=10000, # 超时# **pixel_2,)# 创建两个浏览器上下文
    page = browser.new_page()
    page.goto('http://www.baidu.com')
    print(page.title)
    browser.close()

异步模式

import asyncio
from playwright.async_api import async_playwright
async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        await page.goto("http://www.baidu.com")
        print(await page.title())
        await browser.close()

asyncio.run(main())

防止WebDriver 被检测

js ="""
Object.defineProperties(navigator,{webdriver:{get:()=>undefined}};"""
page.add_init_script(js)

或者
page.add_init_script("""Object.defineProperties(navigator, {webdriver:{get:()=>undefined}});""")

获取源码,文本,属性

获取源码: .content()

page.wait_for_load_state('networkidle')
html = page.content()

获取文本: .text_content()

# ul->li下
brand = element.query_selector('text=品牌:').text_content()

name = ele_items.query_selector('section > div._3KXtu._3jY37 > a').text_content()

获取属性: .get_attribute()

# ul->li下link= element.query_selector('h5 a').get_attribute('href')

wait_for_load_state

"commit ": 接收到网络响应且文档开始加载时(仅显示了页面默认窗口视图下的元素)"domcontentloaded": 认为在 DOMContentLoaded 事件完成时(显示了完整页面)"load": 在 load 事件完成时操作完成(含了所有图片资源)"networkidle": 至少 500 毫秒内没有网络连接时操作完成

页面加载的整个状态变化
Commit -> DOMContentLoaded -> load -> networkidle

监听 response 事件:page.on()

from playwright.sync_api import sync_playwright
 
def on_response(response):
    if'/api/movie/'in response.url and response.status ==200:
        print(response.json())
        print(f'Statue {response.status}:{response.url}')
 
with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)# Page 就是单独的一个浏览器 tab 标签
    page = browser.new_page()
    page.on('response', on_response)# page.on('response', lambda response: on_response(response, product_data, id))
    page.goto('https://spa6.scrape.center/')
    page.wait_for_load_state('networkidle')
    browser.close()
# 监听弹窗
with page.expect_popup() as popup:
    page.evaluate('window.open()')
popup.value.goto('http://www.baidu.com')
# 监听请求
with page.expect_request('**/*login*.png') as first:
    page.goto('http://www.baidu.com')
print(first.value.url)

传参监听

 page.on('response', lambda response: on_response(response, id))for(url, id)in urls:
     pass

滚动

下拉滚动条

page.evaluate("var q=document.documentElement.scrollTop=15000")

鼠标滚动

page.mouse.wheel(0,7000)

截图

 with sync_playwright() as p:
        browser = p.chromium.launch(headless=False, slow_mo=50)
        page = browser.new_page()
        page.goto("http://www.baidu.com")
        page.screenshot(path="example.png")
        browser.close()

获取cookie

browser = playwright.chromium.launch(headless=False)
context = browser.new_context()

cookies = context.storage_state()
cookie ='; '.join([f'{key["name"]}={key["value"]}'forkeyin cookies['cookies']])

CSS,xpath选择器

t伪类选择器
has-text():检测包含(返回找到的所有元素)
text():检测等于(返回第一个找到的元素)

# 选择文本是 Log in 的节点,并点击
page.click("text=Log in",timeout=5000)
page.click("text=你好,请登录")

page.locator(':has-text("All products")').click() 

page.locator("#nav-bar :text('Contact us')").click()
page.locator('[data-test=login-button]').click()
page.locator("[aria-label='Sign in']").click()# 选择 id 为 nav-bar 子孙节点 class 属性值为 contact-us-item,并点击
page.click("#nav-bar .contact-us-item")# 选择文本中包含 Playwright 的 article 节点
page.click("article:has-text('Playwright')")# 选择 id 为 nav-bar 节点中文本值等于 Contact us 的节点
page.click("#nav-bar :text('Contact us')")# 选择 class 为 item-description 的节点,且该节点还要包含 class 为 item-promo-banner 的子节点
page.click(".item-description:has(.item-promo-banner)")# 择的就是一个 input 节点,并且该 input 节点要位于文本值为 Username 的节点的右侧
page.click("input:right-of(:text('Username'))")# xpath
page.click("xpath=//button")

get_by_xxx定位器

●page.get_by_text(文本,kwargs)按文本内容定位。
●page.get_by_role(角色,
kwargs)按角色属性

●page.get_by_label(文本,kwargs)通过关联标签的文本查找表单控件
● page.get_by_test_id(test_id)根据元素的属性定位元素(可以配置其他属性)
page.get_by_placeholder(文本,
kwargs)按占位符查找输入

● 通过其文本替代来定位元素,通常是图像。
●page.get_by_title(文本,**kwargs)按标题定位元素。

page.get_by_label("Password").fill("secret-password")

page.get_by_role("option", name="全部企业").click()
page.get_by_role("button", name="Sign in").click()# 关闭详情弹窗
page.frame_locator("internal:attr=[title=\"详情页\"i]").locator("#enterprise-details-close").click()# 文本内容
page.get_by_text(str(select_text)).click()# 正则匹配定位
page.get_by_role("tab", name=re.compile("风险信息", re.IGNORECASE)).click()

正则定位

循环遍历ul: query_selector_all()

uls = page.query_selector_all('//*[@id="YZhV9-anchor"]//table[@class="ant-table-fixed"]/tbody/tr')forele_itemsin uls:
    title = ele_items.query_selector('section > div._3KXtu._3jY37 > a').text_content()

同级第几个:.nth(2)

点击最后一个按钮
page.click("button >> nth=-1")

page.get_by_placeholder("请输入手机号码").nth(1).click()

文本输入:.fill()

# 标签定位输入
page.locator('text=First Name').fill('Peter')

page.get_by_placeholder("请输入手机号码").nth(1).fill('12345678901')

定位器过滤器:filter

page.locator("a").filter(has_text="密码登录").click()

刷新,前进,后退

page.reload(**kwargs)# 刷新
page.go_back(**kwargs)# 后退
page.go_forward(**kwargs)# 前进

等待

# 等待直到title元素被加载完全
page.locator("title").wait_for()# 会自动等待按钮加载好再执行点击
page.locator("button", has_text="sign up").click()# Playwright 会等待 #search 元素出现在 DOM 中
page.fill('#search', 'query')# Playwright 会等待元素停止动画并接受点击
page.click('#search')# 等待 #search 出现在 DOM 中
page.wait_for_selector('#search', state='attached')# 等待 #promo 可见, 例如具有 `visibility:visible` 
page.wait_for_selector('#promo')# 等待 #details 变得不可见, 例如通过 `display:none`.
page.wait_for_selector('#details', state='hidden')# 等待 #promo 从 DOM 中移除
page.wait_for_selector('#promo', state='detached')# 随机等待
page.wait_for_timeout(random.uniform(2500, 4500))

点击

  • 左键点击:page.click(“id=su”)
  • 点击元素左上角:page.click(‘id=su’, position={‘x’: 0, ‘y’: 0})
  • Shift + click:page.click(“id=su”, modifiers=[‘Shift’])
  • 强制点击:page.click(“id=su”, force=True)
  • 右键点击:page.click(“id=su”, button=‘right’)
  • 双击:page.dblclick(“id=su”)
  • 悬停在元素上:page.hover(‘id=su’)

模拟键盘输入

page.press("id=kw", 'Control+A'):Control+A
page.press('id=kw', 'Enter'):点击回车

# 一个字符一个字符的输入
page.type("id=kw", "playwright", delay=100): 每个字符延迟100ms输入

参考:
https://huaweicloud.csdn.net/63802f5edacf622b8df864ec.html#devmenu22
https://blog.csdn.net/u010698107/article/details/121070336


本文转载自: https://blog.csdn.net/qq_40279560/article/details/129297181
版权归原作者 qq_40279560 所有, 如有侵权,请联系我们删除。

“Playwright 入门详细教程”的评论:

还没有评论