使用python实现一个浏览器自动化的脚本

2025-12-13 0 967

背景

最近工作中有这样一个需求:客户反馈在浏览器操作过程中,重复流程操作太频繁,能不能让浏览器自动操作完成?

在我的认知中,浏览器就是一个用来浏览页面的工具,因此第一反应就是“不可能!绝对不可能!”。领导说,你了解过RPA吗?会后专门查阅了相关资料,在我的理解中,RPA就是一个定制化机器人(脚本流程),通过控制脚本操作显示器,来模拟用户操作的过程。

开始

一开始的时候,我在github上面找了一些开源的项目,例如:PyRPA、RPA-Python、TagUI、openrpa等,但是因为定制化比较强,后期不知道会变成怎么样,因此做的要灵活一些。但是在这些开源项目中,提供了一部分的api,但是在有些地方并不是很容易操作,感觉后面可能会不可控。

但是在我观察中发现,大多数的实现都是通过python实现的,作为一个前端,第一反应就是,为什么不用node和js结合呢,最后反应过来,使用python可以操作整个PC,但是如果你使用node或js,只能说操作浏览器更方便一些了(其实和python差不多),只是python在使用第三方库时候,会存在一定程度的延时。

因此,我决定放弃现有的RPA的项目,自己实现一个自动化的python脚本。

语言选择

关于我为什么选择的python作为语言,其实在前面已经说过了,作为一个前端开发,其实最熟悉的莫过于javascript,另加一些nodejs,那么为什么我没有用nodejs呢?node在前端开发过程中,常常扮演着一个环境的角色,虽然也可以作为一个后端语言来写一些接口或服务(依赖于第三方库),但是很少用到DOM的操作,操作浏览器的DOM,我们通常来说,都是使用js直接操作,或使用jquery等第三方工具。如果要再直接去拦截系统的一些操作,js就不太行了。

因此,采取了python,这一门热度一直很高的语言。主要思路就是,图片的对比,获取点位,模拟用户鼠标,键盘等操作。

浏览器的启动

其实这个启动浏览器,一开始我只是单纯的打开浏览器,但是后面发现,每天第一次启动的时候,都会特别慢,查阅资料也没有找到原因,好像是缓存被清空了吧,网上找了大量的相关资料,最终找到了一个方案:加载时候启动指定驱动程序(浏览器版本与驱动程序需要对应),指定版本浏览器下载,新版驱动下载,114版本前驱动下载,有一部分页面需要科学上网才能访问与下载,建议大家科学上网昂。

一个启动浏览器的demo,这里的driver我在后续就不就行重复的定义了,直接使用了,例如:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

driver = webdriver.Chrome(service=Service(r\”C:\\\\tb2Lot\\\\driver\\\\chromedriver.exe\”))
driver.maximize_window()
driver.execute_script(\”document.charset=\’utf-8\’;\”)
driver.get(\”http://www.baidu.com\”)

这时候我们就已经可以打开浏览器,并操作浏览器调取到百度的页面了,我们想在百度的页面输入并搜索指定内容怎么办呢?这时候我们就需要获取页面的元素节点,然后进行输入了,下面我们来看一下如何在浏览器搜索吧!

在百度进行搜索的方案

首先我们先列举一下目前能够想到的两个方案:

  • 从页面抓取页面元素路径,然后直接点击元素;
  • 整个页面截图,再截取需要点击的小图片,获取需要点击的图片的坐标,点击坐标;

这两种方案对于简单的操作都是可行的,复杂一些的,会出现一些问题,我们先看一下两种方案分别怎么进行操作,然后再来分析一下会遇见怎样的问题吧!

页面抓取元素,直接点击:

使用python实现一个浏览器自动化的脚本

import pyautogui
import pyperclip
import time
from selenium.webdriver.common.by import By
def cvEnter(msg):
pyperclip.copy(msg)
time.sleep(1)
pyautogui.hotkey(\’ctrl\’,\’v\’)
time.sleep(1)
pyautogui.hotkey(\’enter\’) #回车搜索

#driver的定义在本文最上面,这里没有重复写
#…
cvEnter(\”稀土掘金\”)
driver.find_element(By.XPATH,r\’//*[@id=\”su\”]\’).click() #通过浏览器的xpath触发点击事件
time.sleep(2)
driver.find_element(By.XPATH,r\’//*[@id=\”kw\”]\’).clear() #清除输入框
driver.find_element(By.XPATH,r\’//*[@id=\”kw\”]\’).send_keys(\’稀土掘金官网\’) #输入框输入数据
pyautogui.hotkey(\’enter\’)
time.sleep(5)

在上面,其实我们已经使用了两种输入与搜索的方式:

输入

  • 方式一:通过粘贴板,直接进行“c+v”;
  • 方式二:借助python浏览器的driver的send_keys方法,直接键入;

搜索(这里是回车和点击实现的都是搜索)

  • 方式一:使用pyautogui的键盘热键触发;
  • 方式二:借助python浏览器的driver获取浏览器元素,触发该元素的click事件;

通过图片的对比,获取点位进行点击

import pyautogui
import cv2
def getPosiXY(img):
pyautogui.screenshot(\’./pics/screen.png\’) #显示完成之后,截图
screen = cv2.imread(\’./pics/screen.png\’) #加载全屏截图
current = cv2.imread(f\’./tb2lot_pic/{img}\’) #加载比对的图片
result = cv2.matchTemplate(screen, current, cv2.TM_CCOEFF_NORMED) #在screen中寻找current的点位
pos_start = cv2.minMaxLoc(result)[3]
x = int(pos_start[0]) + int(current.shape[1]/2)
y = int(pos_start[1]) + int(current.shape[0]/2)
return x,y

pointX, pointY = getPosiXY(\”query_btn.png\”)
pyautogui.click(pointX, pointY)

在上面的demo中,我们借助cv2库,实现了一个简单的大图中寻找小图的功能,这里在获取之前自动截图并保存到指定目录,小图的名称作为参数,传递到封装的方法中,抓取点位信息,再点击获取到的坐标位置。因为我们抓取的坐标点,因此如果点击的输入框,输入框粘贴数据,就需要直接通过粘贴板进行粘贴了。

为什么我们前面说抓取元素会有问题呢?

首先我们最理想的元素抓取就是,都在一个html中,没有动态的元素,没有切换界面,没有切换弹窗等,但是在实际的应用过程中,往往都是比较复杂的,例如:

  • vue打包的html(元素的id不是固定的,有时候元素节点渲染的问题,嵌套可能有点区别);
  • html嵌套了iframe(直接切换了代码引用的窗口,后面都统一叫做句柄);
  • 选择框的元素,展开和关闭不一致;

以上的问题,都会导致直接抓取元素xpath直接调取时候报错,难道我们就真的不能用xpath进行操作了吗?答案当然是否定的,但是也不是完全,例如在iframe中,我们可以切换句柄,来达到代码引用模块的更换,例如:

#driver的定义在本文最上面,这里没有重复写
#…
iframeSrc = driver.find_element(By.XPATH,r\’/html/body/div/iframe\’)
driver.switch_to.frame(iframeSrc) # 切换句柄到iframe
#driver.switch_to.default_content() #切换到默认的句柄
driver.find_element(By.XPATH,r\’/html/body/form/div/input\’).click()

这样看来,我们iframe也是可以抓取到元素的,不过要等待页面渲染完成之后再去抓取,否则还是会报错的。其余的两个,因为元素是动态的,如果只是id的问题的话,我们可以使用full xpath进行抓取,但是如果元素嵌套都有可能变化的话,就只能采取截图比对的方式了。

此外,我们也再添加一段代码,比如开启浏览器两个标签页的时候与标签页之间的切换怎么处理:

driver.get(\”http://www.baidu.com\”) #打开标签1
driver.execute_script(\”window.open(\’http://www.baidu.com\’);\”) #打开标签2
driver.switch_to.window(driver.window_handles[0]) # 手动切换到标签1

最后

其实到这里,python简单的控制浏览器就已经结束了,其实图片的对比不局限于浏览器,它可以截取PC的屏幕上的所有,因此也可以模拟APP的操作,但是我们在调取的过程中,常常会报错,但是如果打包成了exe文件,我们并不知道报的什么错,因此我们也可以在最外层加上try-except,如果检测到报错,我们可以将报错内容记录在txt中,模拟日志的效果,例如:

from datetime import datetime, timedelta
try:
# some codes
except Exception as e:
now = datetime.now()
date_time = now.strftime(\”%Y-%m-%d %H:%M:%S\”)
data_to_append = f\”{date_time}\\n{e}\\n\\n\”
with open(\’C:\\\\logs\\\\error.txt\’, \’a\’) as file:
file.write(data_to_append)
print(\”Error!\”, e)
driver.quit()
raise ValueError(\”Error!\”)

最后打开预览报错信息,例如:

使用python实现一个浏览器自动化的脚本

代码

import pyautogui
import pyperclip
import time
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from datetime import datetime, timedelta

def cvEnter(msg):
pyperclip.copy(msg)
time.sleep(1)
pyautogui.hotkey(\’ctrl\’,\’v\’)
time.sleep(1)
pyautogui.hotkey(\’enter\’)

try:
driver = webdriver.Chrome(service=Service(r\”C:\\\\pyExe\\\\driver\\\\chromedriver.exe\”)) #驱动写在最上面
driver.maximize_window()
driver.execute_script(\”document.charset=\’utf-8\’;\”)
driver.get(\”http://www.baidu.com\”)
driver.implicitly_wait(10)

cvEnter(\”稀土掘金\”)
driver.find_element(By.XPATH,r\’//*[@id=\”su\”]\’).click() #通过浏览器的xpath触发点击事件、
time.sleep(2)
driver.find_element(By.XPATH,r\’//*[@id=\”kw\”]\’).clear()
driver.find_element(By.XPATH,r\’//*[@id=\”kw\”]\’).send_keys(\’稀土掘金官网\’)
pyautogui.hotkey(\’enter\’)
time.sleep(5)
except Exception as e:
now = datetime.now()
date_time = now.strftime(\”%Y-%m-%d %H:%M:%S\”)
data_to_append = f\”{date_time}\\n{e}\\n\\n\”
with open(\’C:\\\\pyExe\\\\logs\\\\error.txt\’, \’a\’) as file:
file.write(data_to_append)
print(\”Error!\”, e)
driver.quit()
raise ValueError(\”Error!\”)

代码打包

pyinstaller –onefile –noconsole –icon ./favorite.ico ./index.py
# –noconsole 隐藏黑窗口
# –icon ./favorite.ico 打包后的应用图标(路径选对,仅支持ico)
# ./index.py 需要打包的py文件路径

有时候打包完图标没有变化,是默认的图标,可以查看属性,属性中应该是已经有了的,这是因为应用缓存的原因,刷新一下应用程序即可。

重中之重!!!

打包完成之后,将打包后的dist/index.exe文件,移到之前index.py同级目录下,因为如果涉及到图片的比对,会导致图片的位置访问失败。

以上就是使用python实现一个浏览器自动化的脚本的详细内容,更多关于python浏览器自动化的资料请关注脚本之家其它相关文章!

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 编程相关 使用python实现一个浏览器自动化的脚本 https://www.zuozi.net/36595.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务