新一代爬取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_playwright

def 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_playwright

def 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_playwright

with 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_playwright

with 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_playwright

with 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_playwright

with 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 re

with 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_playwright

with 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方法,灵活的控制请求和响应的内容,从而在某些场景下达到某些目的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux 进程(十) 进程替换

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec*函数以执行另一个程序。当进程调用一种exec*函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec*并不创建新进程,所以调用exec*前…

【Bootstrap学习 day13】

Bootstrap5 下拉菜单 下拉菜单通常用于导航标题内&#xff0c;在用户鼠标悬停或单击触发元素时显示相关链接列表。 基础的下拉列表 <div class"dropdown"><button type"button" class"btn btn-primary dropdown-toggle" data-bs-toggl…

虚幻UE 增强输入-第三人称模板增强输入分析与扩展

本篇是增强输入模块&#xff0c;作为UE5.0新增加的模块。 其展现出来的功能异常地强大&#xff01; 让我们先来学习学习一下第三人称模板里面的增强输入吧&#xff01; 文章目录 前言一、增强输入四大概念二、使用步骤1、打开增强输入模块2、添加IA输入动作2、添加IMC输入映射内…

安防监控EasyCVR视频融合/汇聚平台大华热成像摄像机智能告警上报配置步骤

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

第三届先进控制、自动化与机器人国际会议(ICACAR 2024) | Ei、Scopus双检索

会议简介 Brief Introduction 2024年第三届先进控制、自动化与机器人国际会议(ICACAR 2024) 会议时间&#xff1a;2024年5月24-26日 召开地点&#xff1a;中国重庆 大会官网&#xff1a;ICACAR 2024-2024 3rd International Conference on Advanced Control, Automation and Ro…

华为云CES监控与飞书通知

华为云负载均衡连接数监控与飞书通知 在云服务的日常运维中&#xff0c;持续监控资源状态是保障系统稳定性的关键步骤之一。本文通过一个实际案例展示了如何使用华为云的Go SDK获取负载均衡器的连接数&#xff0c;并通过飞书Webhook发送通知到团队群组&#xff0c;以便运维人员…

超维空间M1无人机使用说明书——31、基于模板匹配的物体识别功能

引言&#xff1a;ROS提供的物体识别功能包find_object_2d&#xff0c;该功能包用起来相对简单&#xff0c;只需要简单进行模板匹配即可。需要接显示器进行模板训练&#xff0c;远程比较卡&#xff0c;不建议 一、功能包find_object_2d简介 ROS的优点之一是有大量可以在应用程…

vivado 支持的XDC和SDC命令

支持的XDC和SDC命令 本附录讨论了支持的Xilinx设计约束&#xff08;XDC&#xff09;和Synopsys设计AMD Vivado中的约束&#xff08;SDC&#xff09;命令™ 集成设计环境&#xff08;IDE&#xff09;。 XDC文件中的有效命令 支持的SDC命令 注意&#xff1a;由于所有AMD Tcl命…

基于SSM的人事档案管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

【保研记录】2023年(24届)SE上岸经历

先开个坑&#xff0c;慢慢填~ 个人信息 学校&#xff1a;某双非 专业&#xff1a;软件工程 第四轮学科评估&#xff1a;无&#xff08;对就是没有等级&#xff09; 排名&#xff1a;1/400 竞赛/荣誉&#xff1a;国奖x2&#xff0c;省三好&#xff0c;大英国二&#xff0c;…

【uniapp】多规格选择

效果图 VUE <template> <view><view class"wp-80 pd-tb-40 mg-auto"><button type"warn" click"showDrawer(showRight)">筛选</button></view><!-- 筛选-uni-drawer --><uni-drawer ref"s…

为 validator 对象添加链式调用功能,并 return 校验后的值

目录 一、前置说明1、总体目录2、相关回顾3、本节目标 二、操作步骤1、项目目录2、代码实现3、测试代码4、日志输出 三、后置说明1、要点小结2、下节准备 一、前置说明 1、总体目录 《 pyparamvalidate 参数校验器&#xff0c;从编码到发布全过程》 2、相关回顾 使用 Raise…

JavaScript——BOM中所有对象的常用属性和方法【万字长篇超宝典】

目录 什么是BOM&#xff1f; BOM中的对象 一、window对象 1、控制台打印方法 2、弹窗相关方法 &#xff08;1&#xff09;、alert( )提示框 &#xff08;2&#xff09;、confrim( )交互框 &#xff08;3&#xff09;、prompt( )输入框 3、窗口打开关闭的方法 &#…

企业级实践为“燃料”,大模型助推Kyligence产品力向上

回顾2023年&#xff0c;最火热的科技话题无疑是生成式AI。 从ChatGPT横空出世&#xff0c;到“千模大战”如火如荼&#xff0c;AIGC正式破圈&#xff0c;成为企业数字化转型的新关键词。 在红杉中国《2023企业数字化年度指南》中&#xff0c;通过调研235家企业可知&#xff0…

所有单片机使用的汇编语言是统一的吗?

所有单片机使用的汇编语言是统一的吗&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)主线程反应堆模型的事件添加和处理详解

>>服务器和客户端建立连接和通信流程&#xff1a; 基于多反应堆模型的服务器结构图&#xff0c;这主要是一个TcpServer&#xff0c;关于HttpServer,主要是用了Http协议&#xff0c;核心模块是TcpServer。这里边有两种线程&#xff1a;主线程和子线程。子线程是在线程池里…

windows 10 安装wsl ubuntu

1.首先管理员模式打卡powershell&#xff0c;执行 dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart 2.执行 wsl --update wsl --…

静态网页设计——崩坏3(HTML+CSS+JavaScript)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a; 使用技术&#xff1a;HTMLCSSJS&#xff08;静态网页设计&#xff09; 主要内容&#xff1a;对游戏崩坏3进行简单介绍。 https://www.bilib…

Spring声明式事务业务bug

Spring 针对 Java Transaction API (JTA)、JDBC、Hibernate 和 Java Persistence API (JPA) 等事务 API&#xff0c;实现了一致的编程模型&#xff0c;而 Spring 的声明式事务功能更是提供了极其方便的事务配置方式&#xff0c;配合 Spring Boot 的自动配置&#xff0c;大多数 …

openGauss + Datakit

openGauss Datakit 1. 简介1.1 openGauss1.2 Datakit 2. 环境准备2.1 支持系统2.2 安装包获取2.3 注意事项2.4 系统环境设置 3. openGauss 安装3.1 创建用户和组3.2 创建工作目录3.3 关闭HISTORY记录/关闭交换内存3.4 解压安装包3.5 安装3.6 启动数据库3.7 连接数据库3.8 添加…