当前位置: 首页 > news >正文

crawl4ai智能爬虫(一):playwright爬虫框架详解

文章目录

  • 一、playwright简介
    • 1、任何浏览器 • 任何平台 • 一个 API
    • 2、有弹性 • 没有碎片测试
    • 3、无需权衡 • 无限制
    • 4、完全隔离 • 快速执行
    • 5、强大的工具
  • 二、Playwright vs Selenium
  • 三、playwright安装
  • 四、API使用
    • 1、同步和异步
    • 2、关键对象
      • 1)playwright
      • 2)browser
      • 3)page
    • 3、爬虫关键步骤
    • 4、元素定位
    • 5、xpath定位
    • 6、鼠标模拟
    • 7、键盘输入
    • 8、 js脚本执行:evaluate函数
    • 9、记录脚本
    • 10、反爬虫机制:UA隐匿
  • 五、爬虫示例
  • 六、参考链接
  • 七、总结

一、playwright简介

crawl4ai 是专门为LLM设计的爬虫框架,底层使用playwright实现,本文介绍一下playwrigth爬虫框架。Playwright 是由 Microsoft 开发的一个开源自动化框架,主要用于测试和浏览器自动化。它的一个显著特点是支持 跨浏览器(Chromium、Firefox 和 WebKit)和跨平台(Windows、Linux 和 macOS)。对于爬虫开发者来说,它的价值在于能高效处理现代网页中常见的动态内容、JavaScript 渲染以及复杂的用户交互。

1、任何浏览器 • 任何平台 • 一个 API

跨浏览器。 Playwright 支持所有现代渲染引擎,包括 Chromium、WebKit 和 Firefox。

跨平台。 在 Windows、Linux 和 macOS 上进行本地或 CI 测试,无头或有头。

跨语言。 在 TypeScript、JavaScript、Python、.NET、Java 中使用 Playwright API。

测试移动网络。 适用于 Android 的 Google Chrome 和 Mobile Safari 的原生移动模拟。 相同的渲染引擎可以在桌面和云端运行。

2、有弹性 • 没有碎片测试

自动等待。 Playwright 在执行操作之前等待元素可操作。 它还具有丰富的内省事件。 两者的结合消除了人为超时的需要 - 这是造成碎片测试的主要原因。

网络优先的断言。 Playwright 断言是专门为动态网络创建的。 检查会自动重试,直到满足必要的条件。

追踪。 配置测试重试策略,捕获执行轨迹、视频、屏幕截图以消除碎片。

3、无需权衡 • 无限制

浏览器在不同的进程中运行属于不同来源的网页内容。 Playwright 与现代浏览器架构保持一致,并在进程外运行测试。 这使得 Playwright 摆脱了典型的进程内测试运行器限制。

多重一切。 跨越多个选项卡、多个来源和多个用户的测试场景。 为不同的用户创建具有不同上下文的场景,并在你的服务器上运行它们,所有这些都在一次测试中完成。

可信事件。 悬停元素、与动态控件交互、生成可信事件。 Playwright 使用与真实用户无法区分的真实浏览器输入管道。

测试框架,穿透 Shadow DOM。 Playwright 选择器穿透 Shadow DOM 并允许无缝进入帧。

4、完全隔离 • 快速执行

浏览器上下文。 Playwright 为每个测试创建一个浏览器上下文。 浏览器上下文相当于一个全新的浏览器配置文件。 这提供了零开销的全面测试隔离。 创建新的浏览器上下文只需几毫秒。

登录一次。 保存上下文的身份验证状态并在所有测试中重用它。 这绕过了每个测试中的重复登录操作,但提供了独立测试的完全隔离。

5、强大的工具

代码生成。 通过记录你的操作来生成测试。 将它们保存为任何语言。

Playwright 检查器。 检查页面、生成选择器、逐步执行测试、查看点击点、探索执行日志。

跟踪查看器。 捕获所有信息以调查测试失败。 Playwright 跟踪包含测试执行截屏、实时 DOM 快照、动作资源管理器、测试源等等。

二、Playwright vs Selenium

playwright和selenium都是网页自动化测试框架,Playwright 相较于 Selenium 的主要优势包括:

无需 WebDriver:直接通过开发者工具与浏览器交互,安装更简洁。

自动等待:无需手动添加 sleep,Playwright 会自动等待元素加载。

多语言支持:支持 Python、JavaScript 等多种语言。

双向通信:基于 WebSocket,可实时获取浏览器状态。

  • Selenium 更像是"老牌全能选手",历史悠久、生态庞大。
  • Playwright 更像是"年轻小钢炮",速度快,支持现代网页特性,API 也更友好。
特点SeleniumPlaywright
诞生时间2004 年,历史悠久2020 年,后起之秀
浏览器支持Chrome, Firefox, Safari, IE 等Chromium, Firefox, WebKit(现代浏览器全覆盖)
API 设计早期接口多,稍显复杂API 简洁现代,学习成本低
执行速度较慢,常遇到等待问题更快,更少超时
特殊功能较强大,生态成熟原生支持截图、录制视频、Mock 网络请求

下表对比了 Playwright 和 Selenium 这两个流行的自动化工具在爬虫应用中的关键差异,理解为何 Playwright 在现代 Web 爬虫中更受青睐。

特性对比PlaywrightSelenium
架构与通信基于 WebSocketDevTools 协议 直接与浏览器内核通信,无需额外驱动,通信效率高。通过 WebDriver 协议 经 HTTP/JSON 与浏览器驱动通信,存在中间层,速度相对较慢。
执行速度通常更快,在无头模式下可比 Selenium 快 30%-50%相对较慢。
浏览器管理开箱即用,自带浏览器内核,版本自动匹配,无需单独管理驱动。需手动下载和匹配特定版本的浏览器驱动,维护更繁琐。
等待机制自动等待 元素可交互(如点击、输入),减少手动等待代码,稳定性更高。通常需要开发者手动设置显式或隐式等待,代码更复杂且易因等待时间设置不当失败。
移动端模拟原生支持移动设备参数库,可精准模拟触屏手势等。主要通过 ChromeOptions 模拟分辨率,功能有限。
网络拦截内置强大 API,可直接修改请求头、模拟慢速网络等。需要借助 BrowserMob Proxy 等第三方工具。

三、playwright安装

1)安装python库:

pip install playwright

2)安装浏览器

playwright install
or
python -m playwright install # 仅安装 Chromium, 指定浏览器
python -m playwright install chromium

注意Playwright 需要 Python 3.7 或更高版本。

四、API使用

1、同步和异步

  • 同步方法
from playwright.sync_api import sync_playwright
with sync_playwright() as p:# 启动浏览器browser = p.chromium.launch(headless=False)page = browser.new_page()# 打开网页page.goto("https://www.baidu.com/")# 截取屏幕截图page.screenshot(path="example.png")# 关闭浏览器browser.close()
  • 异步方法

需要使用asyncio库。async 是定义协程,await 用于挂起协程以等待耗时操作完成。

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("https://www.baidu.com/")await page.screenshot(path="example.png")await browser.close()
asyncio.run(main())
  • asyncio

这里简单介绍一下asyncio的使用,asyncio.gather 起两个协程处理。asyncio.run() 自动管理事件循环,以及触发协程异步执行。

import asyncio
async def task(name, delay):print(f"Task {name} started")await asyncio.sleep(delay)print(f"Task {name} finished")
async def main():await asyncio.gather(task("A", 2),task("B", 3))
asyncio.run(main())

asyncio.run 等效如下:

import asyncio
async def hello():print("Hello")await asyncio.sleep(1)print("World")
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()

2、关键对象

playwright爬虫3个关键对象:playwright、browser、page。

1)playwright

全局控制对象,有sync_playwright和async_playwright两个api版本,浏览器对象是由playwright对象启动的。

from playwright.async_api import async_playwright

2)browser

浏览器对象,由playwright启动browser_type.launch()创建一个browser对象,可以选择不同的浏览器

3)page

page是一个标签页,先创建一个标签页,然后使用goto方法跳转到对应网页页面,而selenium中的page是浏览器get后获取的内容,两者概念不一样。

browser.new_page()

browser和page都是和selenium一样的概念,这里多了一个playwright对象来启动browser,3个关键对象的对应关系。

playwrightselenium
全局控制playwrightwebdriver
浏览器对象browserdriver: webdriver.Chrome ,每个浏览器都有特定方法。
标签窗口pagewindow

如下代码示例,以同步方法理清3个对象的层级关系。

playwright版本:

from playwright.sync_api import sync_playwright, Playwrightdef run(playwright: Playwright):firefox = playwright.firefoxbrowser = firefox.launch()page = browser.new_page()page.goto("https://example.com")browser.close()with sync_playwright() as playwright:run(playwright)

对比selenium版本代码示例:

from selenium import webdriver
import time
option = webdriver.ChromeOptions()
option.add_experimental_option("detach", True)# Chrome浏览器
driver = webdriver.Chrome(chrome_options=option)
# driver.set_window_size(500, 500)
# 设置窗口大小
driver.maximize_window()
driver.get('https://www.csdn.net/')# 定位页面元素
app = driver.find_element_by_id("app")
print(dir(app))print(app.text)
print("=======home warp=======")
# 是个对象
home_wrap = driver.find_element_by_class_name("home_wrap")
print(home_wrap.text)# back and forword
#time.sleep(2)
#driver.get("https://blog.csdn.net/ruguowoshiyu/article/details/80539299")
#time.sleep(2)
#driver.back()
#time.sleep(3)
#driver.forward()
#time.sleep(3)
#print(dir(driver))# 新的页面打开窗口,执行js脚本
js = "window.open('https://blog.csdn.net/qq_43965708')"
driver.execute_script(js)# 等待加载完成
time.sleep(3)
print("refresh")
driver.refresh()
time.sleep(3)# 前后窗口切换
windows = driver.window_handles
driver.switch_to.window(windows[0])
time.sleep(3)
# 最后一个窗口
driver.switch_to.window(windows[-1])
time.sleep(3)# 退出浏览器
driver.quit()

3、爬虫关键步骤

详细的API文档官方文档已经介绍很清楚,这里只针对爬虫常见的API做介绍,看一下爬虫常规的步骤:

1)根据url抓取page的html内容

2)解析html,定位某些元素内容,(保存数据or新的url继续爬取子page)

3)鼠标点击和键盘输入,比如登录等功能

4)反爬机制:设置UA代理等。

  • 获取html文本
page.content()
  • 截图功能
page.screenshot(path="example.png")
  • 录制视频
context = browser.new_context(record_video_dir="videos/")
# Make sure to close, so that videos are saved.
context.close()

4、元素定位

Locator 定位器代表了一种随时在页面上查找元素的方法,可以使用 page.locator() 方法创建定位器。如get_by_role返回的就是一个定位器,定位器元素可以执行click函数进行点击。

for li in page.get_by_role('listitem').all():li.click();

定位器的文本信息获取:

texts = page.get_by_role("link").all_text_contents()
texts = page.get_by_role("link").all_inner_texts()

page提供了一些定位方法,比如:

  • get_by_alt_text

通过替代文本alt文本定位图片,然后执行click()方法。

<img alt='Playwright logo'>
page.get_by_alt_text("Playwright logo").click()
  1. get_by_role

根据type类型和name来定位元素。

<h3>Sign up</h3>
<label><input type="checkbox" /> Subscribe
</label>
<br/>
<button>Submit</button>
expect(page.get_by_role("heading", name="Sign up")).to_be_visible()page.get_by_role("checkbox", name="Subscribe").check()page.get_by_role("button", name=re.compile("submit", re.IGNORECASE)).click()
  • get_by_text
<div>Hello <span>world</span></div>
<div>Hello</div>

匹配

# Matches <span>
page.get_by_text("world")# Matches first <div>
page.get_by_text("Hello world")# Matches second <div>
page.get_by_text("Hello", exact=True)# Matches both <div>s
page.get_by_text(re.compile("Hello"))# Matches second <div>
page.get_by_text(re.compile("^hello$", re.IGNORECASE))
  • get_by_title
<span title='Issues count'>25 issues</span>
expect(page.get_by_title("Issues count")).to_have_text("25 issues")

5、xpath定位

特性说明示例
显式写法在表达式前加上 xpath=前缀,明确指定定位策略。page.locator("xpath=//button[@id='submit']")
隐式写法当表达式以 //.//等XPath特有语法开头时,可省略前缀,Playwright会自动识别。page.locator("//button[@id='submit']")
表达式规范XPath 表达式通常需要以 //开头,表示从根节点或任意位置开始匹配。//input[@id='username']
文本匹配支持使用 text(), contains(), starts-with()等函数进行复杂的文本或属性匹配。//a[text()='Sign In'] //div[contains(@class, 'error')]

6、鼠标模拟

  1. click方法

点击某个位置。

mouse.click(x, y)
mouse.click(x, y, **kwargs)
  1. 双击
mouse.dblclick(x, y)
mouse.dblclick(x, y, **kwargs)
  1. 滚动 wheel
mouse.wheel(delta_x, delta_y)

7、键盘输入

  1. 输入字符
page.keyboard.insert_text("嗨")
  1. 按键事件keyboard.press 相当与down()+up()。
page = browser.new_page()
page.goto("https://keycode.info")
page.keyboard.press("a")
page.screenshot(path="a.png")
page.keyboard.press("ArrowLeft")
page.screenshot(path="arrow_left.png")
page.keyboard.press("Shift+O")
page.screenshot(path="o.png")
browser.close()

8、 js脚本执行:evaluate函数

# 获取浏览器语言
lan = page.evaluate("window.navigator.language;")
print(lan)

9、记录脚本

playwright codegen命令用于录制脚本,target参数 选择脚本语言类型。比如:

playwright codegen --target python -o test_script.py https://www.baidu.com/

在这里插入图片描述

10、反爬虫机制:UA隐匿

有时爬虫需要设置UA代理,模拟浏览器行为,可以构造UA代理,比如如下代码:

from playwright.sync_api import sync_playwright
with sync_playwright() as playwright:browser = playwright.chromium.launch(headless=False)page = browser.new_page(user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36')page.goto("https://www.baidu.com/")page.wait_for_timeout(10000)browser.close()

五、爬虫示例

比如爬取csdn网站哪,获取csdn的某个文章的title信息

<h1 class="title-article" id="articleContentId">如何快速学习一个网络协议?</h1>

使用xpath获取文章的title信息,代码示例如下:

from playwright.sync_api import sync_playwright
with sync_playwright() as p:# 启动浏览器browser = p.chromium.launch(headless=False)page = browser.new_page()print(dir(page))# 打开网页page.goto("https://blog.csdn.net/qq_40036519/article/details/152513893")# 截取屏幕截图# page.screenshot(path="example.png")html = page.content()print(html)lan = page.evaluate("window.navigator.language;")print(lan)title=page.locator("//h1[@id='articleContentId']")for ti in title.all_inner_texts():print(ti)# 关闭浏览器browser.close()

六、参考链接

  • Playwright 官网
  • Playwright 开源地址
  • Playwright API 文档
  • playwright中文网
  • 菜鸟教程

  • selenium 官方文档

七、总结

总的来说,Playwright 凭借其现代的设计、卓越的性能和开发者友好的 API,非常适合用于构建高效、稳定的爬虫系统,尤其是在应对复杂动态网站时优势明显。

http://www.dtcms.com/a/473625.html

相关文章:

  • 探究Java、C语言、Python、PHP、C#与C++在多线程编程中的核心差异与应用场景
  • 国外网站模板网站建设ui培训班好
  • 瑞安建设公司网站旅游网站系统的设计与实现
  • MongoDB-基本介绍(一)基本概念、特点、适用场景、技术选型
  • 国产之光金仓数据库,真能平替MongoDB?实测来了!
  • 网站开发需要学什么语言wordpress所有栏目循环输出
  • 低代码革命:拖拽式界面生成器与API网关的深度集成
  • “事件风暴 → 上下文映射 → 模块化”在 ABP vNext 的全链路模板
  • 如何在Linux服务器上部署jenkins?
  • 2.1 阵列信号处理基础
  • Centos7下docker的jenkins下载并配置jdk与maven
  • 网络数据侦探:抓包工具在爬虫开发中的艺术与科学
  • 手搓docker - 实现篇
  • soho做网站谷歌推广网站建设采购项目
  • 深入理解HTTP协议的本质
  • 以太网通信
  • 网站运营推广方式网站建设需要学编程么
  • 开源合规:GPL-3.0项目的专利风险规避
  • Java基于SpringBoot的医院门诊管理系统,附源码+文档说明
  • windows查询与设备通讯的mac地址
  • Tauri Android 开发踩坑实录:从 Gradle 版本冲突到离线构建成功
  • nuxt3中使用defineAsyncComponent懒加载组件,但其中的loadingComponent和errorComponent为什么不生效
  • GIS中最常用的编程语言
  • 用wordpress做的网站有哪些公司网站建设成本
  • 网站网页怎么设计无代码开发软件
  • 阿里发布「夸克 AI 眼镜」:融合阿里购物、地图、支付生态;苹果拟收购计算机视觉初创 Prompt AI丨日报
  • 【精品模板鉴赏】WORD版企业IT管理参考资料模板-数据安全|信息安全|网络安全|应急预案|灾备恢复..
  • Vue 核心特性详解:计算属性、监听属性与事件交互实战指南
  • 建设银行 嘉定 网站ai的优点和缺点
  • LeetCode 刷题【115. 不同的子序列】