新一代爬取JavaScript渲染页面的利器-playwright(二)

接上文:新一代爬取JavaScript渲染页面的利器-playwright(一)
  上文我们主要讲了Playwright的特点、安装、基本使用、代码生成的使用以及模拟移动端浏览,这篇我们主要讲下Playwright的选择器以及常见的操作方法。

6.选择器

  我们可以把传入的字符串称为Element Selector,除了它已经支持的CSS选择器、XPath,Playwright还为它拓展了一些方便好用的规则,例如直接根据文本内容筛选,根据节点的层级结构筛选等。

  • 文本选择

  文本选择支持text=这样的语句进行筛选,例如:

page.click(“text=Log in”)

  该句代表点击文本内容是Log in的节点

  • CSS选择器

  例如根据id/class筛选:

page.click(“button”)
page.click(“nav-bar .contact-us-item”)

  根据特定的节点属性进行筛选:

page.click(“[data-test-login-button]”)
page.click(“[aria-label=‘Sign in’]”)

  • CSS选择器+文本值

  常用的方法是has-text和text,前者代表节点中包含指定的字符串,后者代表节点中的文本值和指定的字符串完全匹配,示例如下:

page.click(“article:has-text(‘playwright’)”)
page.click(“#nav-bar :text(‘Contact us’)”)

  • CSS选择器+节点关系

  CSS选择器还可以结合文本关系来筛选节点,例如指定另一个选择器,示例如下:

page.click(“.item-description:has(.item-promo-banner)”)

  这里选择的就是class为item-description的节点,且该节点还要包含class为item-promo-banner的子节点。
  另外还可以结合一些相对位置关系,例如使用right-of指定位于某个节点右侧的节点。

page.click(“input:right-of(:text(‘Username’))”)

  这里选择的就是一个input节点,并且该节点要位于Username的节点的右侧。

  • XPath

  XPath也是支持的,不过是xpath关键字需要我们自己来指定,示例如下:

page.click(“xpath=//button”)

7.常用操作方法

  下面介绍些一些常用的操作方法。例如click(点击),fill(输入)等等,这些方法都属于page对象,所有方法都可以从page对象的API文档查找。
  下面介绍几个常见的操作方法的用法。

  • 事件监听

  page对象提供一个on方法,用来监听页面中发生的各个事件,例如close,console,load,request,response等。
  这里我们监听response事件,在每次页面请求得到相应的时候会触发这个事件,我们可以设置回调方法来获取响应中的全部信息,示例如下:

from playwright.sync_api import sync_playwrightdef on_response(response):print(f'State{response.status}:{response.url}')with sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()page.on('response',on_response)page.goto('https://spa6.scrape.center')page.wait_for_load_state('networkidle')browser.close()

  可以看到输出结果如下;
在这里插入图片描述

  我们在创建page对象后,就开始监听response事件,同时将回调方法设置为on_response,其接收一个参数,然后输出响应中的状态码和链接。
  如果观察网页请求包内容可以发现,这个输出结果正好对应浏览器network中所有的请求和响应。
  这个网站的真实的数据都是Ajax加载的,同时Ajax请求中还带有加密参数,不容易轻易获取。但是有了on_response方法,如果我们想截取Ajax请求,是非常容易的。

from playwright.sync_api import sync_playwrightdef on_response(response):if '/api/movie' in response.url and response.status == 200:print(response.json)with sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()page.on('response',on_response)page.goto('https://spa6.scrape.center')page.wait_for_load_state('networkidle')browser.close()

  可以看到我们通过on_response方法拦截了Ajax请求,直接拿到了响应结果,即使这个Ajax请求中有加密参数也不用担心,因为这里截获的是最后的请求结果。

  • 获取页面源代码

  调用page对象的content方法可以获取网页源码。

from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()page.goto('https://spa6.scrape.center')page.wait_for_load_state('networkidle')html = page.content()print(html)browser.close()

  运行结果就是页面源代码,然后可以再利用一些解析工具就可以提取到想要的信息了。

  • 页面点击

  实现页面点击的方法就是click方法,click方法的API定义如下:

page.click(selector,**kwargs)

  其中,必须传入的数据是selector,其他参数都是可选的。selector代表选择器,用来匹配想要点击的节点,如果有多个节点都匹配,只使用第一个。
  其他比较重要的参数如下:

  • click_count:点击次数,默认为1.

  • timeout:等待找到要点击节点的超时的时间,默认为30秒。

  • position:需要传入如一个字典,要带有x和y属性,代表点击位置相对节点左上角的偏移量。

  • force:即使按钮设置了不可点击,也要强制点击,默认是False。

  • 文本输入

  文本输入对应的方法是fill,其API定义如下:

page.fill(selector,value,**kwargs)

  第一个selector代表选择器,value代表输入的内容,还可以通过timeout参数查找对应节点的最长等待时间。

  • 获取节点属性

  除了操作节点本身,我们也可以获得节点的属性,方法是get_attribute。

page.get_attribute(selector,name,**kwargs)
  这个有两个必传参数,selector和name,name代表要获取属性的名称。示例如下:

from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()page.goto('https://spa6.scrape.center')page.wait_for_load_state('networkidle')href = page.get_attribute('a.name','href')print(href)browser.close()

  这里调用了get_attribute方法,传入的selector参数值是a.name,代表查找class为name的a的节点,name的参数传入了href,输出结果如下。

/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWIx

  这里看到对应节点的href属性只输出了一条,因为如果匹配了多个节点,就只返回第一个。

  • 获取多个节点

  对于获取所有节点,我们可以使用query_selector_all方法来获取。它会返回节点列表,通过遍历得到单个节点后,可以调用上面介绍的针对单个节点的方法完成一些操作和获取属性。示例如下:

# 获取多个节点
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()page.goto('https://spa6.scrape.center')page.wait_for_load_state('networkidle')elements = page.query_selector_all('a.name')for element in elements:print(element.get_attribute('href'))print(element.text_content())browser.close()

  这里通过query_selector_all方法获取了所有可以匹配得到的节点,每个节点对应一个ElementHandle对象,然后通过该对象的get_attribute和text_content得到节点的属性和文本。运行结果如下:
在这里插入图片描述

  • 获取单个节点

  多个节点用query_selector_all,那么单个节点自然就是query_selector,如果匹配到多个节点,那么就只返回第一个。
示例如下:

from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()page.goto('https://spa6.scrape.center')page.wait_for_load_state('networkidle')element = page.query_selector('a.name')print(element.get_attribute('href'))print(element.text_content())browser.close()

  运行后可以看到只返回了第一个节点的信息。

  • 网络劫持

  利用route方法可以实现网络劫持和修改操作,例如修改request的属性,修改响应结果等。

from playwright.sync_api import sync_playwright
import rewith sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()def cancel_request(route,request):route.abort()page.route(re.compile(r"(\.png)|(\.jpg)"),cancel_request)page.goto('https://spa6.scrape.center')page.wait_for_load_state('networkidle')page.screenshot(path='no_picture.png')browser.close()

  这里调用了route方法,第一个参数通过正则表达式传入了URL路径,cancel_request 方法接收两个参数,一个是route,代表CallableRoute对象,另一个是request代表Request对象,这里我们直接调用CallableRoute对象的abort方法,取消了这次请求,导致最终的结果是取消全部图片的加载。结果截图如下图所示:
在这里插入图片描述
  我们在爬取的过程中只关心的是图片的url,图片是否加载出来并不重要,这样可以提高整个页面的加载速度,提高爬取效率。
  另外还可以利用这个功能对一些响应内容进行修改,例如我们可以将相应的结果直接修改为我们自定义的文本内容。
  我们先定义一个文本文件,命名demo.html,内容如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Hack Response</title>
</head>
<body><h1>Hack Response</h1>
</body>
</html>

  代码编写如下:

from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()def modify_response(route,request):print(f"Modifying response for {request.url}")route.fulfill(path = "./demo.html")page.route('**/*', modify_response)page.goto('https://spa6.scrape.center')page.wait_for_load_state('networkidle')browser.close()

  这里我们使用callableRoute对象的fulfill方法指定了一个本地文件。
在这里插入图片描述
  这时可以看到响应结果已经被修改了,但是URL没有变,我们可以利用route方法,灵活的控制请求和响应的内容,从而在某些场景下达到某些目的。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git 本地仓库

本地仓库 start.bat 启动

k_d树, KNN算法学习笔记_1 距离和范数

k_d树, KNN算法学习笔记_1 距离和范数 二维树中最近邻搜索的示例。这里&#xff0c;树已经构建好了&#xff0c;每个节点对应一个矩形&#xff0c;每个矩形被分割成两个相等的子矩形&#xff0c;叶子对应于包含单个点的矩形 From Wikipedia 1&#xff0e; k k k近邻法是基本且简…

使用“反向代理服务器”的优点是什么?

反向代理服务器是一种网络架构模式&#xff0c;通常位于客户端和实际服务器之间&#xff0c;用于处理客户端请求并转发到实际服务器。以下是使用反向代理服务器的优点&#xff1a; 1.安全性&#xff1a;反向代理服务器可以提供额外的安全层。通过在反向代理服务器上配置防火墙和…

opencv006 绘制直线、矩形、⚪、椭圆

绘制图形是opencv经常使用的操作之一&#xff0c;库中提供了很多有用的接口&#xff0c;今天来学习一下吧&#xff01; &#xff08;里面的函数和参数还是有点繁琐的&#xff09; 最终结果显示 函数介绍 直线 line(img, pt1, pt2, color, thickness, lineType, shift) img: 在…

GO语言笔记1-变量与基本数据类型

变量使用步骤 声明赋值使用 package main import "fmt" func main(){var age int //声明一个 int类型的变量叫ageage 18 //给变量用 赋值fmt.Println(age) //使用变量 输出变量的值 } 编译运行输出变量值 变量的四种使用方式 package main import "fmt&q…

nginx配置图片服务器

目录 一&#xff1a;访问流程 二&#xff1a;缓存服务器配置 三&#xff1a;上传图片直接上传到图片服务器 四&#xff1a;加快图片访问 一&#xff1a;访问流程 访问缓存服务器(上面安装nginx反向代理到图片服务器&#xff0c;对外提供服务)->图片服务器 二&#xff1…

Ajax基础入门_Ajax概述,同步与异步,Axios的使用,JSON数据及FastJSON的使用

Ajax 文章目录 Ajax1 概述2 作用3 同步和异步3.1 同步3.2 异步 4 代码编写4.1 服务端4.2 客户端 5 Axios5.1 使用5.2 代码5.2.1 前端5.2.2 后端 5.3 请求方法别名 6 JSON6.1 概述6.2 JSON 基础语法6.2.1 定义格式6.2.2 js 对象与JSON的转换 6.3 发送异步请求携带参数6.4 JSON串…

[PyTorch][chapter 9][李宏毅深度学习][CNN]

前言&#xff1a; 卷积神经网络&#xff08;Convolutional Neural Networks&#xff09;是一种深度学习模型或类似于人工神经网络的多层感知器&#xff0c;常用来分析视觉图像。卷积神经网络的创始人是着名的计算机科学家Yann LeCun&#xff0c;目前在Facebook工作&#xff0c;…

WSL 与真实 linux 环境区别有多大?

随着 Windows 系统的不断发展和完善&#xff0c;WSL&#xff08;Windows Subsystem for Linux&#xff09;作为 Windows 10 的一个功能&#xff0c;为 Windows 用户提供了一个可以在 Windows 环境下运行 Linux 二进制可执行文件的环境。然而&#xff0c;尽管 WSL 为用户提供了一…

BERT(从理论到实践): Bidirectional Encoder Representations from Transformers【3】

这是本系列文章中的第3弹,请确保你已经读过并了解之前文章所讲的内容,因为对于已经解释过的概念或API,本文不会再赘述。 本文要利用BERT实现一个“垃圾邮件分类”的任务,这也是NLP中一个很常见的任务:Text Classification。我们的实验环境仍然是Python3+Tensorflow/Keras…

python打包exe

打包python绘制玫瑰花_python生成玫瑰花-CSDN博客 这个链接的程序 隐藏 控制台窗口&#xff08;如果你的程序是GUI&#xff0c;不是控制台应用可以选用&#xff0c;比如本案例的送你玫瑰花就是白底的&#xff09; 报错的话&#xff0c;可能没有pyinstaller这个库 参考&#x…

动手学深度学习一:环境安装与数据学习

2024&#xff0c;重新开始深度学习。 第一步&#xff1a;李沐动手学深度学习 课程网址&#xff1a;https://courses.d2l.ai/zh-v2/ 包含教材和视频网址链接 Jupyter notebook安装 目前在本地先使用cpu版本pytorch&#xff0c;我的本地已经安装好conda&#xff0c;跟着教材创建…

Android中的Intent

一.显式Intent 显示Intent是明确目标Activity的类名 1. 通过Intent(Context packageContext, Class<?> cls)构造方法 2.通过Intent的setComponent()方法 3.通过Intent的setClass/setClassName方法 通过Intent(Context packageContext, Class<?> cls)构造方法 通…

买工业用品就找震坤行,提供震坤行商品数据,数据分析的API接口

要接入API接口以采集电商平台上的商品数据&#xff0c;可以按照以下步骤进行&#xff1a; 1、找到可用的API接口&#xff1a;首先&#xff0c;需要找到支持查询商品信息的API接口。这些信息通常可以在电商平台的官方文档或开发者门户网站上找到。 2、注册并获取API密钥&#x…

【普中开发板】基于51单片机的篮球计分器液晶LCD1602显示( proteus仿真+程序+设计报告+讲解视频)

基于普中开发板51单片机的篮球计分器液晶LCD1602显示 1.主要功能&#xff1a;讲解视频&#xff1a;2.仿真3. 程序代码4. 设计报告5. 设计资料内容清单&&下载链接资料下载链接&#xff08;可点击&#xff09;&#xff1a; 基于51单片机的篮球计分器液晶LCD1602显示 ( pr…

信息论与编码期末复习——概念论述简答题(一)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…

hyperf console 执行

一、原理描述 hyperf中&#xff0c;不难发现比如自定义控制器中获取参数&#xff0c;hyperf.php中容器获取&#xff0c;传入的都是接口&#xff0c;而不是实体类。 这是因为框架中的配置文件有设置对应抽象类的子类&#xff0c;框架加载的时候将其作为数组&#xff0c;使用的…

读算法霸权笔记11_微目标

1. 脸书 1.1. 一份请愿书属于脸书了&#xff0c;而社交网络的算法会对如何最大限度地利用这份请愿书做出判断 1.1.1. 脸书的算法在决定谁能看到我的请愿书时会把所有因素都考虑在内 1.2. 通过改变信息推送的方式&#xff0c;脸书研究了我们…

ssm基于Web的汽车客运订票系统的设计与实现论文

毕业设计&#xff08;论文&#xff09; 汽车客运订票系统 姓 名 ______________________ 学 号 ______________________ 班 级 ______________________ 专 业 ______________________ 院 部 ______________________ 指导教师 ______________________ 年 月 日 目 录 目 录 …

[排序算法] 如何解决快速排序特殊情况效率低的问题------三路划分

前言 在[C/C]排序算法 快速排序 (递归与非递归)一文中,对于快速排序的单趟排序一共讲了三种方法: hoare、挖坑法、双指针法 ,这三种方法实现的快速排序虽然在一般情况下效率很高,但是如果待排序数据存在大量重复数据,那这几种方法的效率就很低,而为了解决快速排序在这样特殊情况…