Playwright使用教程【附爬取Leetcode题目URLs以及有道翻译小软件】

news2024/11/15 15:46:02

前言

playwright是微软设计的一款工具,可以爬取网页,还可以自动化测试自己编写的网站,而且不像bs4、request编写爬虫那么复杂,也不需要考虑反爬技术,只需要知道最基础的前端知识,就可以高效、便捷的编写爬虫代码

但是这篇文章不可能将playwright的所有功能全部讲到,但是覆盖了最基础的一些知识,如果想更系统的学习,可以参考playwright python的官方文档:https://playwright.dev/python/docs/intro

也非常推荐白月黑羽的教程:Playwright web自动化 - Python版_哔哩哔哩_bilibili

安装步骤

pip install pytest-playwright
playwright install

简单demo

使用下面命令可以开启录制

playwright codegen

在这里插入图片描述

右边窗口会自动根据左边浏览器做的操作进行记录,下面是自动生成的代码模板,定义了同步操作(不是异步)的playwright类,并输入到run函数中,browser这句代码开辟新的进程,打开了playwright自带的浏览器chromium,这个可以自己改为其他的浏览器(参考官网),headless为False时,执行过程会打开浏览器,否则将不会显示。

from playwright.sync_api import Playwright, sync_plawright, expect

def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()

    # ---------------------
    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)

在左边浏览器键入www.baidu.com,右边代码就新增了代码,表示跳转到了这个界面

page.goto("https://www.baidu.com/")

然后点击输入框,并输入nihao,就会新增下面这些代码,其中locator是定位器,page.locator("#kw") 定位到的是输入的文本框,即定位到网页中的一个部件,后面的click、fill、press分别表示点击、填充、输入回车等操作,对部件的操作见Actions | Playwright Python

page.locator("#kw").click()
page.locator("#kw").fill("nihao")
page.locator("#kw").press("Enter")

这样一来就可以自动设计代码啦,同时还可以使用tracing模块来记录执行的过程

context = browser.new_context()
context.tracing.start(snapshots=True, sources=True, screenshots=True)
...
context.tracing.stop(path="trace.zip")

然后在终端执行就可以显示整个的过程,左边为playwright的各种操作,右边有Action,Before和After显示每一步的动作、先前状态和执行过后的状态

playwright show-trace trace.zip

在这里插入图片描述

这样一个简单的demo,打开baidu网站,查询nihao,就实现啦

from playwright.sync_api import Playwright, sync_playwright, expect

def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    context.tracing.start(snapshots=True, sources=True, screenshots=True)
    page = context.new_page()
    page.goto("https://www.baidu.com/")
    page.locator("#kw").click()
    page.locator("#kw").fill("nihao")
    page.locator("#kw").press("Enter")
    context.tracing.stop(path="trace.zip")
    context.close()
    browser.close()

with sync_playwright() as playwright:
    run(playwright)

任务描述和预备知识

我将通过一个实际应用来说明如何使用playwright,获取到leetcode上每一个题目的url网址。

进入leetcode官网,点击题库
在这里插入图片描述

然后跳到第二页
在这里插入图片描述

发现网页为:https://leetcode.cn/problemset/?page=2,其中?右边为参数,表示在第几页,没有page参数时默认第1页,我们发现每一页都有50个题目(除了第一页有51个题目,需要特殊处理)

点击F12打开开发者模式,右边选择“元素”菜单

在这里插入图片描述

点击下面的图表,然后在左侧点击控件,可以查看到第52题这块对应的源码,右边源码中有属性href=“/problems/n-queens-ii”,这就是我们想要获取的信息,但是这个网页不完整,点击这个网站后,可以看到网页变为了https://leetcode.cn/problems/n-queens-ii/description,所以还需要加上前缀:“https://leetcode.cn” 和后缀 ”/description“

在这里插入图片描述
在这里插入图片描述

我们的目标是获取到每一个题目的href信息,并保存在一个txt文件当中

选择器定位

前面使用到了page.locator方法,里面的参数就是我们去定位组件的标准,我们不能完全依靠codegen这一个方法自动化完成代码,如果需要输出一些信息,就不能指望它了,所以这一节将介绍如何定位元素以及元素的一些操作

我们首先在模板中填写下面的代码,暂时不处理最后一页的题目,遍历第1页到第72页的题目,然后goto到该网站,并等待5s,之所以等待5s是因为需要等网页加载完毕后,才能提取到相关的信息,否则会加载错误

for page_index in trange(1, 73):
    page.goto(f"https://leetcode.cn/problemset/?page={page_index}")
    page.wait_for_timeout(5000)

接下来就是定位了,例如某一个分块有class属性,如下所示,则locator里面可以写为page.locator(".truncate") ,这里的"."表示匹配的class元素

<div class='truncate'>
    nihao
</div>

然后可以调用.inner_text()可以打印这一个locator的文本信息

lc = page.locator(".truncate")
print(lc.inner_text())	# 输出nihao

然而一个html网页中可能有多个块的class包含truncate,那么 page.locator(".truncate") 就会定位到所有的块,这时候就需要使用.all()方法,将所有定位到的locator转变为list对象,然后我们遍历list,再打印文本信息

lcs = page.locator(".truncate").all()
for lc in lcs:
    print(lc.inner_text())

注意,如果locator定位到的元素个数大于1,则不能执行fill、click、inner_text等操作,需要使用all()将其转换为列表,下面是locator的一些方法和用法

locator(".truncate").count()		# 匹配元素的个数
locator(".truncate").first			# 第一个元素
locator(".truncate").last			# 最后一个元素
locator(".truncate").nth(3)			# 第三个元素

除了使用class定位,还可以使用id定位,一般而言html中的id是唯一的,例如下面的代码可以使用 page.locator("#animal") 来定位,"#"表示id

<div id='animal'>
    nihao
</div>

如果一个块中有多个class类别,例如下面的例子,使用 page.locator(".animal.plant") 定位,注意中间不能有空格

<div class='animal plant'>
    nihao
</div>

还可以直接使用page.locator(“div”)来定位这个div块,如果不是上述情况,而是其他的属性名,则可以用方括号来指示,例如下面的例子可以用 page.locator("[role=region]") 定位

<div role='region'>
    nihao
</div>

还可以是模糊匹配,包含 *=, ^=, *=等方式

[href*=www] -> href属性包含www的元素
[href^=www] -> href属性以www开头的元素
[href$=www] -> href属性以www结尾的元素

我们还可以通过多级选择器来选择,在下面的例子中,想定位nihao,可以使用 page.locator(".a > .b)" 定位,“>” 表示直接子节点,如果想定位oahin,还可以使用子孙节点的定位方式,使用空格来隔开 page.locator(".a .d") ,这样就跳过了中间节点".c"

<div class='a'>
	<div class='b'>
		nihao
    </div>
	<div class='c'>
        <div class='d'>
            oahin
        </div>
    </div>
</div>

实际定位

弄清楚如何定位后,接下来,我们要获取每一页中的所有题目的信息,找到某一个题目的信息,代码如下

在这里插入图片描述

可以使用下面的代码定位,但是如何确定是否准确定位到呢,一个方法就是执行一遍代码,打印出来定位到的块,查看是否符合预期,但是这样太麻烦了,浏览器中可以帮助我们查看

lcs = page.locator(".truncate .h-5")

在右上方(下方是另一个界面了)输入Ctrl + F开启搜索功能,输入.truncate .h-5,看到我们找到了50个元素,刚好对应一页中题目的个数

在这里插入图片描述

我们可以通过下面的代码获取到第i个元素的url地址,使用到了get_attribute方法获取某一个属性的值

lcs = page.locator(".truncate .h-5")
lcs.nth(i).get_attribute("href")

然后我们可以将url补充完整,特殊处理一下第一页51道题目的情况,将题目索引以及url保存在urls.txt文件当中,编写完成下面的脚本

from playwright.sync_api import Playwright, sync_playwright
from tqdm import trange

def run(playwright: Playwright) -> None:
    with open('urls.txt', 'w') as f:
        browser = playwright.chromium.launch(headless=True)
        context = browser.new_context()
        page = context.new_page()
        cnt = 1
        for page_index in trange(1, 73):
            page.goto(f"https://leetcode.cn/problemset/?page={page_index}")
            page.wait_for_timeout(5000)
            lcs = page.locator(".truncate .h-5")
            for problem_index in range(50):     # 第一页的题目索引要加一
                problem_page = f'https://leetcode.cn{lcs.nth(problem_index + int(page_index == 1)).get_attribute("href")}/description'
                f.write(str(cnt) + ' ' + problem_page + '\n')
                cnt += 1
                f.flush()
    context.close()
    browser.close()

with sync_playwright() as playwright:
    # 获取系统参数
    run(playwright)

最终获取了信息啦!

在这里插入图片描述

如果对您有帮助,请不要吝啬您的赞呀,你们的鼓励是我最大的动力!

补充样例

下面的例子是打开有道翻译,输入英文,返回翻译后的信息代码,如果您感兴趣,可以看看哦,使用到的方法都差不多~

from playwright.sync_api import Playwright, sync_playwright, expect
import re

def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=True)
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://fanyi.youdao.com/#/") 
    page.locator(".close").click()
    page.locator("div").filter(has_text=re.compile(r"^翻译$")).click()
    page.locator(".ic_language_arrowdown").first.click()
    page.get_by_text("英语").first.click()
    page.wait_for_timeout(1000)
    while True:
        word = input("=" * 100 + "\n>>> ")
        page.locator("#js_fanyi_input").click()
        page.locator("#js_fanyi_input").fill(word)
        page.wait_for_timeout(1000)
        if page.locator(".pron").count():   # 单个单词,打印音标以及所有意思
            for text in page.locator(".pron").all_inner_texts():
                split = text.split()
                if not split:
                    continue
                else:
                    print(f"{split[0]}: /{split[1]}/")
            print(page.locator(".paraphrase-container").first.inner_text())
        else:   # 句子,直接显示翻译
            print(page.locator(".tgt.un-step-trans").inner_text())

    # ---------------------
    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)

执行效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1914701.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法训练记录——Day43】

Day43——动态规划Ⅴ 1.kamacoder52_携带研究材料2.leetcode518_零钱兑换Ⅱ3.leetcode377_组合总和Ⅳ 完全背包 1.kamacoder52_携带研究材料 思路&#xff1a;这里每种材料可以选择无数次&#xff0c;因此属于完全背包&#xff0c; 首先回顾一下01背包的核心代码 for(int i 0…

vue3 + tsx 表格 Action 单独封装组件用法

前言 先上图看右侧列 action 的 UI 效果&#xff1a; 正常来说&#xff0c;如果一个表格的附带 action 操作&#xff0c;我们一般会放在最右侧的列里面实现&#xff0c;这个时候有些UI 框架支持在 SFC 模板里面定义额外的 solt&#xff0c;当然如果不支持&#xff0c;更通用的…

医疗器械网络安全 | 漏洞扫描、渗透测试没有发现问题,是否说明我的设备是安全的?

尽管漏洞扫描、模糊测试和渗透测试在评估系统安全性方面是非常重要和有效的工具&#xff0c;但即使这些测试没有发现任何问题&#xff0c;也不能完全保证您的医疗器械是绝对安全的。这是因为安全性的评估是一个多维度、复杂且持续的过程&#xff0c;涉及多个方面和因素。以下是…

7.10号小项目部分说明

总体说明 糖锅小助手 我这次主要对上次糖锅小助手界面添加了一个侧边栏&#xff08;侧边输入框放置了三个按钮&#xff0c;可以跳转到其他ai聊天界面&#xff0c;还可以退出聊天界面回到登录界面&#xff09;和一个日期输入框&#xff08;日期输入框获取时间&#xff0c;根据时…

史上最齐全电动弃流装置(弃流控制柜/流量式雨水弃流装置)这里都有,井座式、304不锈钢材质

电动弃流装置组成部分有&#xff1a;PLC控制柜、雨量传感器/电磁流量计、弃流装置 进出水管可以定制不同接口&#xff0c;可以适用于连接波纹管、PVC管 电动弃流装置的工作原理如下&#xff1a; 首先&#xff0c;雨量传感器或电磁流量计实时监测降雨量或水流流量等相关数据&…

TCP 握手数据流

这张图详细描述了 TCP 握手过程中&#xff0c;从客户端发送 SYN 包到服务器最终建立连接的整个数据流转过程&#xff0c;包括网卡、内核、进程中的各个环节。下面对每个步骤进行详细解释&#xff1a; 客户端到服务器的初始连接请求 客户端发送 SYN 包&#xff1a; 客户端发起…

AI降痕工具:一键去除论文中的AI代写痕迹

在这个充满创意和创新的时代&#xff0c;AI已经渗透到我们生活的方方面面。然而&#xff0c;随着AI的飞速发展&#xff0c;AI的痕迹在论文创作中愈发明显。 这不禁让人思考&#xff0c;如何让论文回归纯粹&#xff0c;展现人类独有的思考和见解。“论文去AI痕迹”不仅是对学术…

vue3-openlayers WebGL加载地图(栅格切片、矢量切片)

本篇介绍一下使用vue3-openlayers WebGL加载地图&#xff08;栅格切片、矢量切片&#xff09; 1 需求 vue3-openlayers WebGL加载地图&#xff08;栅格切片、矢量切片&#xff09; 2 分析 栅格切片使用ol-webgl-tile-layer 矢量切片使用ol-vector-tile-layer&#xff08;默…

海外视频媒体发布/发稿:如何在国外媒体以视频的形式宣发

1. 背景介绍 在如今数字化时代&#xff0c;每个国家都拥有着各自的视频媒体平台&#xff0c;而主流媒体也都纷纷加入了视频发布的行列。视频媒体的宣发形式主要包括油管Youtube等视频分享平台&#xff0c;以及图文配合的发布方式。通过在视频中夹带链接&#xff0c;媒体可以以…

服务器安全运维方案介绍

随着信息技术的飞速发展&#xff0c;服务器已成为企业信息化建设的核心基础设施。然而&#xff0c;服务器安全运维问题也日益凸显&#xff0c;如何保障服务器的稳定运行和数据安全&#xff0c;已成为企业面临的重要挑战。本文旨在介绍一套全面的服务器安全运维方案&#xff0c;…

『C + ⒈』‘\‘

&#x1f942;在反斜杠(\)有⒉种最常用的功能如下所示&#x1f44b; #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main(void) {int a 10;int b 20;int c 30;if (a 10 &&\b 20 &&\c 30){printf("Your print\n");}else{prin…

【leetcode刷题笔记】02.复写零

题目&#xff1a; 思路&#xff1a; 代码实现 class Solution { public:void duplicateZeros(vector<int>& arr) {//1.模拟异地操作int prev0,cur0;int lenarr.size();while(cur<len){//arr[prev]不是0就都走一步if(arr[prev]!0){prev;cur;}//arr[prev]是0就pre…

FlutterFlame游戏实践#15 | 生命游戏 - 演绎启动

theme: cyanosis 本文为稀土掘金技术社区首发签约文章&#xff0c;30天内禁止转载&#xff0c;30天后未获授权禁止转载&#xff0c;侵权必究&#xff01; Flutter\&Flame 游戏开发系列前言: 该系列是 [张风捷特烈] 的 Flame 游戏开发教程。Flutter 作为 全平台 的 原生级 渲…

78000A 信号分析软件

思仪(Ceyear) 78000A 信号分析软件 78000A 信号分析软件是一款能够在电脑上运行的应用软件&#xff0c;预留了开放式的 SCPI 控制指令&#xff0c;可以远程控制信号/频谱分析仪采集数据&#xff0c;也可以回放仿真数据或者采集的历史数据文件&#xff0c;执行通用频谱测量、矢…

Windows 下安装 Memcached

Memcached 安装包下载 官网上并未提供 Memcached 的 Windows 平台安装包。 我们可以使用以下链接来下载&#xff0c;你需要根据自己的系统平台及需要的版本号点击对应的链接下载即可&#xff1a; 32位系统 1.2.5版本&#xff1a;http://static.jyshare.com/download/memcache…

(Windows环境)FFMPEG编译,包含编译x264以及x265

本文使用 MSYS2 来编译 ffmpeg 一、安装MSYS2 MSYS2 是 Windows 下的一组编译套件&#xff0c;它可以在 Windows 系统中模拟 Linux 下的编译环境&#xff0c;如使用 shell 运行命令、使用 pacman 安装软件包、使用 gcc (MinGW) 编译代码等。 MSYS2 的安装也非常省心&#x…

视频共享交换平台LntonCVS视频监控平台智慧加油站安全管理方案

加油站作为危化品行业的一部分&#xff0c;日常的加油和卸油作业安全至关重要。目前国内加油站的管理主要依赖于人为管控、监控摄像头和人工巡检&#xff0c;这些方法存在效率低下和反应滞后的问题。为了有效应对安全风险&#xff0c;急需引入人工智能、物联网和大数据技术&…

Android14系统应用统一裁剪方案

Android14系统应用统一裁剪方案 背景 当前移除集成到系统里的应用,一般都是根据应用名,到各个mk文件里逐个在PRODUCT_PACKAGES中删除;这种方法,耗时而且不易管理集成到系统里的应用;需要有一个统一管理删除不需要应用的方案。 方案 参考PRODUCT_PACKAGES变量,添加PRO…

NVIDIA良心给显卡免费升级,只为挨更多的骂

起猛了&#xff0c;还真的以为 NVIDIA 良心发现了。 众所周知&#xff0c;英伟达对于咱们普通游戏玩家向来不屑一顾。只因为游戏业务在 NVIDIA 收入中占比较少。 在最新的 40 系显卡 RTX 4070 Ti Super 显卡中&#xff0c;NVIDIA悄悄给它来了一次核心「升级」&#xff0c;将原…

开发问卷微信小程序:从零到部署

开发问卷小程序&#xff1a;从零到部署 引言 微信小程序作为一种轻量级的应用形式&#xff0c;以其便捷性和广泛的用户基础&#xff0c;成为开发者的新宠。本博客将详细介绍如何使用HBuilderX编辑器和uView UI框架&#xff0c;开发一款问卷小程序。 环境准备 HBuilderX下载与…