【python爬虫】设计自己的爬虫 4. 封装模拟浏览器 PyppeteerSimulate

Pyppeteer是Puppeteer的Python版实现
Pyppeteer的背后实际上有一个类似于Chrome的浏览器–Chromium

class PyppeteerSimulate(BrowserSimulateBase):def __init__(self):self.browser = Noneself.page = None# 启动浏览器# is_headless 是否开启无头模式# is_cdp 是否使用cdp (Chrome Devtools Protocol)async def start_browser(self, is_headless=False, is_dev=False, proxy=None, is_socks5=False, *args, **kwargs):"""异步启动浏览器。Args:is_headless (bool, optional): 是否开启无头模式。默认为 False。is_dev (bool, optional): 是否启用调试模式。默认为 False。proxy (str, optional): 代理设置。默认为 None。is_socks5 (bool, optional): 是否使用 SOCKS5 代理。默认为 False。*args, **kwargs: 其他参数。Returns:BrowserContext: 已启动的浏览器对象。"""args = ['--disable-infobars', f'--window-size={WINDOW_WIDTH},{WINDOW_HEIGHT}']if proxy:proxy_protocol = 'socks5://' if is_socks5 else 'http://'args.append('--proxy-server=' + proxy_protocol + proxy)self.browser = await launch(headless=is_headless, devtools=is_dev, args=args, autoClose=True)return self.browserasync def start_page(self, url: str):"""在已启动的浏览器上创建新页面并访问指定的 URL。Args:url (str): 要访问的页面的 URL。Returns:Page: 新创建的页面对象。"""context = await self.browser.createIncognitoBrowserContext()self.page = await context.newPage()await self.page.setViewport({'width': WINDOW_WIDTH, 'height': WINDOW_HEIGHT})await self.page.evaluateOnNewDocument('Object.defineProperty(navigator, "webdriver", {get: () => undefined})')await self.page.goto(url)return self.page# 显式等待async def wait_until_element(self, selector_location, timeout=None, selector_type=None):"""等待直到页面中出现指定的元素。参数:selector_location (str): 要等待的元素选择器。返回:element (ElementHandle or None): 如果找到元素,返回元素的句柄,否则返回None。"""try:element = await self.page.waitForSelector(selector_location)return elementexcept Exception as e:print(f"等待元素时发生错误: {str(e)}")return None# 等待时间 sasync def wait_for_time(self, timeout):"""在异步上下文中等待指定的时间(秒)。参数:timeout (int): 等待的时间(秒)。无返回值。"""await self.page.waitFor(timeout * 1000)# 查找多个元素async def find_elements(self, selector_location, selector_type=None):"""使用指定的选择器查找所有匹配的元素。参数:selector_location (str): 要查找的元素选择器。selector_type (str, optional): 选择器类型(例如 'css', 'xpath' 等)。返回:elements (List): 匹配的元素列表。"""elements = await self.page.JJ(selector_location)return elements# 查找元素async def find_element(self, selector_location, selector_type=None):"""使用指定的选择器查找第一个匹配的元素。参数:selector_location (str): 要查找的元素选择器。selector_type (str, optional): 选择器类型(例如 'css', 'xpath' 等)。返回:element (ElementHandle or None): 匹配的元素句柄,如果未找到则返回 None。"""return await self.page.J(selector_location)# iframe 查找多个元素async def find_iframe_elements(self, selector_location, iframe):"""在指定的 iframe 中查找所有匹配的元素。参数:selector_location (str): 要查找的元素选择器。iframe (Frame): 包含要查找元素的 iframe 对象。返回:elements (List): 匹配的元素列表。"""return await iframe.JJ(selector_location)# iframe 查找元素async def find_iframe_element(self, selector_location, iframe):"""在指定的 iframe 中查找第一个匹配的元素。参数:selector_location (str): 要查找的元素选择器。iframe (Frame): 包含要查找元素的 iframe 对象。返回:element (ElementHandle or None): 匹配的元素句柄,如果未找到则返回 None。"""return await iframe.J(selector_location)# 查找并获取元素属性的值async def find_element_all_eval(self, selector_location, selector_type=None, script_command=None):"""使用指定的选择器和脚本命令查找所有匹配的元素。参数:selector_location (str): 要查找的元素选择器。script_command (str, optional): 用于评估元素的自定义脚本命令。返回:elements (List): 匹配的元素列表。"""return await self.page.JJeval(selector_location, script_command)# 浏览器回退async def go_back(self):"""在浏览器中执行后退操作,返回上一页。无返回值。"""await self.page.goBack()# 浏览器前进async def go_forward(self):"""在浏览器中执行前进操作,前往下一页。无返回值。"""await self.page.goForward()# 获取cookiesasync def get_cookies(self):"""获取当前页面的所有 Cookies。返回:cookies (List): 包含所有 Cookies 的列表。"""return await self.page.cookies()# 添加cookiesasync def add_cookie(self, cookie):"""向当前页面添加一个 Cookie。参数:cookie (dict): 要添加的 Cookie 对象,应包含 'name' 和 'value' 属性。无返回值。"""await self.page.setCookie(cookie)# 删除cookiesasync def del_cookies(self):"""删除当前页面的所有 Cookies。无返回值。"""await self.page.deleteCookie()# 切换选项卡async def switch_tab(self, tab):"""在浏览器窗口中切换到指定的标签页。参数:tab (int): 要切换到的标签页的索引号。无返回值。"""pages = await self.browser.pages()await pages[tab].bringToFront()# 刷新页面async def reload_page(self):"""重新加载当前页面。无返回值。"""await self.page.reload()# 截图async def screen_page(self, file_path=None):"""截取当前页面的屏幕截图。参数:file_path (str, optional): 截图文件保存的路径和名称。如果未提供路径,将在当前工作目录保存。无返回值。"""await self.page.screenshot(path=file_path)# 关闭浏览器async def close_browser(self):"""关闭浏览器。无返回值。"""await self.browser.close()# 获取页面内容async def get_content(self):"""获取当前页面的内容。返回:content (str): 当前页面的HTML内容。"""return await self.page.content()# 点击async def click(self, selector_location, selector_type=None):"""在指定的选择器位置执行点击操作。参数:selector_location (str): 要点击的元素选择器。selector_type (str, optional): 选择器类型(例如 'css', 'xpath' 等)。无返回值。"""return await self.page.click(selector_location)# 输入内容async def send_keys(self, selector_location, input_content, selector_type=None):"""在指定的选择器位置输入文本内容。参数:selector_location (str): 要输入文本的元素选择器。input_content (str): 要输入的文本内容。selector_type (str, optional): 选择器类型(例如 'css', 'xpath' 等)。无返回值。"""return await self.page.type(selector_location, input_content)async def drag_and_drop(self, source, target):"""模拟拖拽操作,将源元素拖拽到目标元素位置。参数:source (ElementHandle): 要拖拽的源元素句柄。target (ElementHandle): 拖拽的目标元素句柄。无返回值。"""source_box = await source.boundingBox()target_box = await target.boundingBox()# 计算源和目标元素的中心点source_x = source_box['x'] + source_box['width'] / 2source_y = source_box['y'] + source_box['height'] / 2target_x = target_box['x'] + target_box['width'] / 2target_y = target_box['y'] + target_box['height'] / 2# 模拟拖拽操作await self.page.mouse.move(source_x, source_y)await self.page.mouse.down()await self.page.mouse.move(target_x, target_y)await self.page.mouse.up()# iframeasync def to_iframe(self, iframe):"""切换到指定名称的 iframe。参数:iframe_name (str): 要切换到的 iframe 的名称。返回:target_frame (Frame or None): 匹配的 iframe 对象,如果未找到则返回 None。"""frames = self.page.frames# 找到你需要的iframefor frame in frames:if frame.name == iframe:target_frame = framereturn target_frame

测试代码

# 测试代码
async def test_pyppeteer():await pyppeteer_simulate.start_browser()# await pyppeteer_simulate.start_page('https://www.baidu.com/')# await pyppeteer_simulate.wait_until_element('.s_ipt')# await pyppeteer_simulate.wait_for_time(2)# await pyppeteer_simulate.screen_page('../../files/pyppeteer_example.png')# print(await pyppeteer_simulate.get_content())await pyppeteer_simulate.start_page('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')target_frame = await pyppeteer_simulate.to_iframe('iframeResult')# 在特定的iframe中查找元素source = await pyppeteer_simulate.find_iframe_element('#draggable', target_frame)target = await pyppeteer_simulate.find_iframe_element('#droppable', target_frame)await pyppeteer_simulate.drag_and_drop(source, target)await pyppeteer_simulate.close_browser()if __name__ == '__main__':asyncio.get_event_loop().run_until_complete(test_pyppeteer())

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

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

相关文章

win10报错“api-ms-win-crt-string-l1-1-0.dll文件丢失,软件无法启动”,快速修复方法,亲测有效

api-ms-win-crt-string-l1-1-0.dll是Windows操作系统中的一个动态链接库文件,属于Microsoft C Runtime Library。它包含了Windows操作系统需要运行C程序的一些基本系统函数,比如字符串处理、内存分配等。 它的作用主要是提供一些基本的、用于支持C语言编…

go语言gin框架的基本使用

1.首先在linux环境上安装go环境,这个网上搜搜就行 2.初始化一个go mod,网上搜搜怎么初始化 3.下面go代码的网址和端口绑定自己本机的就行 4.与另一篇CSDN一起食用,效果更好哟---> libcurl的get、post的使用-CSDN博客 package mainimpo…

算法每日一题: 被列覆盖的最多行数 | 二进制 - 状态压缩

大家好,我是星恒 今天的题目又是一道有关二进制的题目,有我们之前做的那道 参加考试的最大学生数的 感觉,哈哈,当然,比那道题简单多了,这道题感觉主要的考点就是二进制,大家可以好好总结一下这道…

04、Kafka ------ CMAK 各个功能的作用解释(Cluster、集群、Broker、位移主题、复制因子、领导者副本、主题)

目录 启动命令:CMAK的用法★ 在CMAK中添加 Cluster★ 在CMAK中查看指定集群★ 在CMAK中查看 Broker★ 位移主题★ 复制因子★ 领导者副本和追随者副本★ 查看主题 启动命令: 1、启动 zookeeper 服务器端 小黑窗输入命令: zkServer 2、启动 …

苹果电脑Markdown写作工具:ulysses mac软件介绍

ulysses for mac是一款Markdown写作工具,支持Markdown拼写检查、语音识别、iCloud同步、版本管理等功能,并且可以导出为 PDF、word、RTF、TXT、Markdown、HTML 和 ePub等文件格式。 ulysses for mac软件介绍 适用于Mac,iPad和iPhone的终极写…

试除法判定质数算法总结

知识概览 质数的定义 在大于1的整数中,如果只包含1和本身这两个约数,就被称为质数,或者叫素数。 质数的判定——试除法 暴力算法 时间复杂度 改进算法 时间复杂度 暴力算法:时间复杂度O(n) 算法模版 bool is_pr…

简单几步使用Spring整合MyBatis(含配置多数据源和多Mapper XML文件路径)

1. 逻辑梳理 我们先分析下使用者视角:代码中使用Mapper接口对数据进行数据库操作,具体的SQL在Mapper xml文件中。可以看到Mapper接口和Mapper xml是有一定的关联关系的,我们的配置思路也是如此,就是把两者绑定起来即可。 首先我…

Idea live template

1:打印入参日志的配置 log.info("$methodName$ 方法入参: $argsLog$",$argsJson$); methodName:methodName() argsLog:groovyScript( "def result; def params\"${_1}\".replaceAll([\\\\[|\\\\]|\\\\s], ).split(,).toList(); for(i 0; i <…

【负载均衡oj】(七)ojserver

一.目的 负责负载均衡&#xff0c;获取网站首页&#xff0c;通过网络罗调用编译并运行并提供结果给用户。根据用户的操作提供不同的功能。采用mvc结构。使用 ctemplate文字模板做数据渲染 m在这里指的是和数据的交互&#xff0c;可以用文件或者sql交互。在使用文件的情况下&a…

CISP-DSG和CDGA该如何选择?

同样是数据治理&#xff0c;CDGA证书和CISP-DSG证书&#xff0c;它们之间有什么区别和各自的优势呢❓ 1️⃣CISP-DSG CISP-DSG证书聚焦于信息an全领域&#xff0c;特别guan注数据an全治理。 国际知名zi询机构Gartner用“风暴之眼”比喻“数据an全治理”&#xff0c;&#x1f44…

hyperf 基础合集

目前合计不包括数据库。 hyperf 一、搭建 -CSDN博客hyperf 二、路由 -CSDN博客hyperf 三、中间件 -CSDN博客hyperf 四、控制器 -CSDN博客hypef 五、请求及响应 -CSDN博客hyperf 六、异常处理 -CSDN博客hypef 七、配置文件的使用_-CSDN博客hypef 八、缓存 -CSDN博客hypef 九、日…

【机器学习】线性回归·可运行源码

一&#xff0c;基础函数库 import numpy as np from utils.features import prepare_for_trainingclass LinearRegression:def __init__(self, data, labels, polynomial_degree0, sinusoid_degree0, normalize_dataTrue):"""1.对数据进行预处理操作2.先得到所…

ssm基于java web 的QQ村旅游网站的设计+vue论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统旅游信息管理难度大&#xff0c;容错率低&#xff0c;管理…

el-select下拉框 change事件返回该项所有数据

主要代码 value-key <template><div><el-selectv-model"value"value-key"label"placeholder"请选择"change"selectChange"><el-optionv-for"item in options":key"item.label":label"…

云计算历年题整理

第一大题 第一大题计算 给出计算连接到EC2节点的EBS的高可用性(HA)的数学公式&#xff0c;如场景中所述&#xff1b;计算EC2节点上的EBS的高可用性(HA)&#xff1b;场景中80%的AWS EC2节点用于并行处理&#xff0c;总共有100个虚拟中央处理单元(vCPUs)用于处理数据&#xff0…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)在EventLoop的任务队列中添加新任务

任务队列是一个链表&#xff0c;每个节点包含channel类型、文件描述符和操作类型。在添加节点时&#xff0c;需要考虑线程同步&#xff0c;并确保节点被正确地添加到链表中。节点的操作可以写到另一个函数中&#xff0c;以便于程序的维护。在添加任务节点时&#xff0c;需要加互…

迅为RK3588开发板使用 FFMpeg 进行推流

Debian/Ubuntu 系统使用以下命令安装 FFMpeg &#xff0c;如下图所示&#xff1a; apt-get install ffmpeg 使用 ifconfig 查看开发板 ip 为 192.168.1.245 如下图所示&#xff1a; 使用 FFMpeg 推流一个 mp4 视频进行测试&#xff0c;作者将测试视频 test.mp4 放在了根目录下…

轻松入门:Anaconda 在 PyCharm 中的配置与应用指南

1 Anaconda Anaconda 和 Conda 是两个相关但不同的概念。 Anaconda 是一个免费且开源的发行版&#xff0c;包含了 Python 和 R 语言的数据科学和机器学习相关的众多包&#xff0c;它包括 Conda、Python、Jupyter Notebook 等多个科学计算和数据科学中常用的应用。 Anaconda 通过…

2022年山东省职业院校技能大赛高职组信息安全管理与评估—开发测试服务器解析

任务5:开发测试服务器 目录 任务5:开发测试服务器 解题方法:

外包干了4个月,技术退步明显了...

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01; 而我已经在一个企业干了四…