最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用python實(shí)現(xiàn)一個(gè)瀏覽器自動(dòng)化的腳本

 更新時(shí)間:2024年04月29日 10:34:22   作者:進(jìn)階的小叮當(dāng)  
最近工作中有這樣一個(gè)需求:客戶反饋在瀏覽器操作過程中,重復(fù)流程操作太頻繁,能不能讓瀏覽器自動(dòng)操作完成?所以本文給大家介紹了如何使用python實(shí)現(xiàn)一個(gè)瀏覽器自動(dòng)化的腳本,感興趣的朋友可以參考下

背景

最近工作中有這樣一個(gè)需求:客戶反饋在瀏覽器操作過程中,重復(fù)流程操作太頻繁,能不能讓瀏覽器自動(dòng)操作完成?

在我的認(rèn)知中,瀏覽器就是一個(gè)用來瀏覽頁面的工具,因此第一反應(yīng)就是“不可能!絕對(duì)不可能!”。領(lǐng)導(dǎo)說,你了解過RPA嗎?會(huì)后專門查閱了相關(guān)資料,在我的理解中,RPA就是一個(gè)定制化機(jī)器人(腳本流程),通過控制腳本操作顯示器,來模擬用戶操作的過程。

開始

一開始的時(shí)候,我在github上面找了一些開源的項(xiàng)目,例如:PyRPA、RPA-Python、TagUI、openrpa等,但是因?yàn)槎ㄖ苹容^強(qiáng),后期不知道會(huì)變成怎么樣,因此做的要靈活一些。但是在這些開源項(xiàng)目中,提供了一部分的api,但是在有些地方并不是很容易操作,感覺后面可能會(huì)不可控。

但是在我觀察中發(fā)現(xiàn),大多數(shù)的實(shí)現(xiàn)都是通過python實(shí)現(xiàn)的,作為一個(gè)前端,第一反應(yīng)就是,為什么不用node和js結(jié)合呢,最后反應(yīng)過來,使用python可以操作整個(gè)PC,但是如果你使用node或js,只能說操作瀏覽器更方便一些了(其實(shí)和python差不多),只是python在使用第三方庫時(shí)候,會(huì)存在一定程度的延時(shí)。

因此,我決定放棄現(xiàn)有的RPA的項(xiàng)目,自己實(shí)現(xiàn)一個(gè)自動(dòng)化的python腳本。

語言選擇

關(guān)于我為什么選擇的python作為語言,其實(shí)在前面已經(jīng)說過了,作為一個(gè)前端開發(fā),其實(shí)最熟悉的莫過于javascript,另加一些nodejs,那么為什么我沒有用nodejs呢?node在前端開發(fā)過程中,常常扮演著一個(gè)環(huán)境的角色,雖然也可以作為一個(gè)后端語言來寫一些接口或服務(wù)(依賴于第三方庫),但是很少用到DOM的操作,操作瀏覽器的DOM,我們通常來說,都是使用js直接操作,或使用jquery等第三方工具。如果要再直接去攔截系統(tǒng)的一些操作,js就不太行了。

因此,采取了python,這一門熱度一直很高的語言。主要思路就是,圖片的對(duì)比,獲取點(diǎn)位,模擬用戶鼠標(biāo),鍵盤等操作。

瀏覽器的啟動(dòng)

其實(shí)這個(gè)啟動(dòng)瀏覽器,一開始我只是單純的打開瀏覽器,但是后面發(fā)現(xiàn),每天第一次啟動(dòng)的時(shí)候,都會(huì)特別慢,查閱資料也沒有找到原因,好像是緩存被清空了吧,網(wǎng)上找了大量的相關(guān)資料,最終找到了一個(gè)方案:加載時(shí)候啟動(dòng)指定驅(qū)動(dòng)程序(瀏覽器版本驅(qū)動(dòng)程序需要對(duì)應(yīng)),指定版本瀏覽器下載,新版驅(qū)動(dòng)下載,114版本前驅(qū)動(dòng)下載,有一部分頁面需要科學(xué)上網(wǎng)才能訪問與下載,建議大家科學(xué)上網(wǎng)昂。

一個(gè)啟動(dòng)瀏覽器的demo,這里的driver我在后續(xù)就不就行重復(fù)的定義了,直接使用了,例如:

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")

這時(shí)候我們就已經(jīng)可以打開瀏覽器,并操作瀏覽器調(diào)取到百度的頁面了,我們想在百度的頁面輸入并搜索指定內(nèi)容怎么辦呢?這時(shí)候我們就需要獲取頁面的元素節(jié)點(diǎn),然后進(jìn)行輸入了,下面我們來看一下如何在瀏覽器搜索吧!

在百度進(jìn)行搜索的方案

首先我們先列舉一下目前能夠想到的兩個(gè)方案:

  • 從頁面抓取頁面元素路徑,然后直接點(diǎn)擊元素;
  • 整個(gè)頁面截圖,再截取需要點(diǎn)擊的小圖片,獲取需要點(diǎn)擊的圖片的坐標(biāo),點(diǎn)擊坐標(biāo);

這兩種方案對(duì)于簡單的操作都是可行的,復(fù)雜一些的,會(huì)出現(xiàn)一些問題,我們先看一下兩種方案分別怎么進(jìn)行操作,然后再來分析一下會(huì)遇見怎樣的問題吧!

頁面抓取元素,直接點(diǎn)擊:

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的定義在本文最上面,這里沒有重復(fù)寫
#...
cvEnter("稀土掘金")
driver.find_element(By.XPATH,r'//*[@id="su"]').click() #通過瀏覽器的xpath觸發(fā)點(diǎn)擊事件
time.sleep(2)
driver.find_element(By.XPATH,r'//*[@id="kw"]').clear() #清除輸入框
driver.find_element(By.XPATH,r'//*[@id="kw"]').send_keys('稀土掘金官網(wǎng)') #輸入框輸入數(shù)據(jù)
pyautogui.hotkey('enter')
time.sleep(5)

在上面,其實(shí)我們已經(jīng)使用了兩種輸入與搜索的方式:

輸入

  • 方式一:通過粘貼板,直接進(jìn)行“c+v”;
  • 方式二:借助python瀏覽器的driver的send_keys方法,直接鍵入;

搜索(這里是回車和點(diǎn)擊實(shí)現(xiàn)的都是搜索)

  • 方式一:使用pyautogui的鍵盤熱鍵觸發(fā);
  • 方式二:借助python瀏覽器的driver獲取瀏覽器元素,觸發(fā)該元素的click事件;

通過圖片的對(duì)比,獲取點(diǎn)位進(jìn)行點(diǎn)擊

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}') #加載比對(duì)的圖片
    result = cv2.matchTemplate(screen, current, cv2.TM_CCOEFF_NORMED) #在screen中尋找current的點(diǎn)位
    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庫,實(shí)現(xiàn)了一個(gè)簡單的大圖中尋找小圖的功能,這里在獲取之前自動(dòng)截圖保存到指定目錄,小圖的名稱作為參數(shù),傳遞到封裝的方法中,抓取點(diǎn)位信息,再點(diǎn)擊獲取到的坐標(biāo)位置。因?yàn)槲覀冏ト〉淖鴺?biāo)點(diǎn),因此如果點(diǎn)擊的輸入框,輸入框粘貼數(shù)據(jù),就需要直接通過粘貼板進(jìn)行粘貼了。

為什么我們前面說抓取元素會(huì)有問題呢?

首先我們最理想的元素抓取就是,都在一個(gè)html中,沒有動(dòng)態(tài)的元素,沒有切換界面,沒有切換彈窗等,但是在實(shí)際的應(yīng)用過程中,往往都是比較復(fù)雜的,例如:

  • vue打包的html(元素的id不是固定的,有時(shí)候元素節(jié)點(diǎn)渲染的問題,嵌套可能有點(diǎn)區(qū)別);
  • html嵌套了iframe(直接切換了代碼引用的窗口,后面都統(tǒng)一叫做句柄);
  • 選擇框的元素,展開和關(guān)閉不一致;
  • ...

以上的問題,都會(huì)導(dǎo)致直接抓取元素xpath直接調(diào)取時(shí)候報(bào)錯(cuò),難道我們就真的不能用xpath進(jìn)行操作了嗎?答案當(dāng)然是否定的,但是也不是完全,例如在iframe中,我們可以切換句柄,來達(dá)到代碼引用模塊的更換,例如:

#driver的定義在本文最上面,這里沒有重復(fù)寫  
#...
iframeSrc = driver.find_element(By.XPATH,r'/html/body/div/iframe')
driver.switch_to.frame(iframeSrc) # 切換句柄到iframe
#driver.switch_to.default_content() #切換到默認(rèn)的句柄
driver.find_element(By.XPATH,r'/html/body/form/div/input').click()

這樣看來,我們iframe也是可以抓取到元素的,不過要等待頁面渲染完成之后再去抓取,否則還是會(huì)報(bào)錯(cuò)的。其余的兩個(gè),因?yàn)樵厥莿?dòng)態(tài)的,如果只是id的問題的話,我們可以使用full xpath進(jìn)行抓取,但是如果元素嵌套都有可能變化的話,就只能采取截圖比對(duì)的方式了。

此外,我們也再添加一段代碼,比如開啟瀏覽器兩個(gè)標(biāo)簽頁的時(shí)候與標(biāo)簽頁之間的切換怎么處理:

driver.get("http://www.baidu.com") #打開標(biāo)簽1
driver.execute_script("window.open('http://www.baidu.com');") #打開標(biāo)簽2
driver.switch_to.window(driver.window_handles[0]) # 手動(dòng)切換到標(biāo)簽1

最后

其實(shí)到這里,python簡單的控制瀏覽器就已經(jīng)結(jié)束了,其實(shí)圖片的對(duì)比不局限于瀏覽器,它可以截取PC的屏幕上的所有,因此也可以模擬APP的操作,但是我們?cè)谡{(diào)取的過程中,常常會(huì)報(bào)錯(cuò),但是如果打包成了exe文件,我們并不知道報(bào)的什么錯(cuò),因此我們也可以在最外層加上try-except,如果檢測到報(bào)錯(cuò),我們可以將報(bào)錯(cuò)內(nèi)容記錄在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!")

最后打開預(yù)覽報(bào)錯(cuò)信息,例如:

代碼

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")) #驅(qū)動(dòng)寫在最上面
    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觸發(fā)點(diǎn)擊事件、
    time.sleep(2)
    driver.find_element(By.XPATH,r'//*[@id="kw"]').clear()
    driver.find_element(By.XPATH,r'//*[@id="kw"]').send_keys('稀土掘金官網(wǎng)')
    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 打包后的應(yīng)用圖標(biāo)(路徑選對(duì),僅支持ico)
# ./index.py 需要打包的py文件路徑

有時(shí)候打包完圖標(biāo)沒有變化,是默認(rèn)的圖標(biāo),可以查看屬性,屬性中應(yīng)該是已經(jīng)有了的,這是因?yàn)閼?yīng)用緩存的原因,刷新一下應(yīng)用程序即可。

重中之重!??!

打包完成之后,將打包后的dist/index.exe文件,移到之前index.py同級(jí)目錄下,因?yàn)槿绻婕暗綀D片的比對(duì),會(huì)導(dǎo)致圖片的位置訪問失敗。

以上就是使用python實(shí)現(xiàn)一個(gè)瀏覽器自動(dòng)化的腳本的詳細(xì)內(nèi)容,更多關(guān)于python瀏覽器自動(dòng)化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python?pickle模塊實(shí)現(xiàn)Python對(duì)象持久化存儲(chǔ)

    Python?pickle模塊實(shí)現(xiàn)Python對(duì)象持久化存儲(chǔ)

    這篇文章主要介紹了Python?pickle模塊實(shí)現(xiàn)Python對(duì)象持久化存儲(chǔ),pickle?是?python?語言的一個(gè)標(biāo)準(zhǔn)模塊,和python安裝時(shí)共同安裝好的一個(gè)模塊。下文基于pickle模塊展開實(shí)現(xiàn)Python對(duì)象持久化存儲(chǔ)的詳細(xì)內(nèi)容,需要的朋友可以參考一下
    2022-05-05
  • Python反射的用法實(shí)例分析

    Python反射的用法實(shí)例分析

    這篇文章主要介紹了Python反射的用法,結(jié)合實(shí)例形式分析了Python反射機(jī)制所涉及的幾個(gè)常用方法與相關(guān)使用技巧,需要的朋友可以參考下
    2018-02-02
  • 快速解決vue.js 模板和jinja 模板沖突的問題

    快速解決vue.js 模板和jinja 模板沖突的問題

    今天小編就為大家分享一篇快速解決vue.js 模板和jinja 模板沖突的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • python3實(shí)現(xiàn)暴力窮舉博客園密碼

    python3實(shí)現(xiàn)暴力窮舉博客園密碼

    這篇文章主要介紹了python3實(shí)現(xiàn)暴力窮舉博客園密碼的相關(guān)資料,需要的朋友可以參考下
    2016-06-06
  • pymysql 插入數(shù)據(jù) 轉(zhuǎn)義處理方式

    pymysql 插入數(shù)據(jù) 轉(zhuǎn)義處理方式

    今天小編就為大家分享一篇pymysql 插入數(shù)據(jù) 轉(zhuǎn)義處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • python list中append()與extend()用法分享

    python list中append()與extend()用法分享

    列表是以類的形式實(shí)現(xiàn)的?!皠?chuàng)建”列表實(shí)際上是將一個(gè)類實(shí)例化。因此,列表有多種方法可以操作
    2013-03-03
  • Python基礎(chǔ)之enumerate()函數(shù)用法詳解

    Python基礎(chǔ)之enumerate()函數(shù)用法詳解

    enumerate()函數(shù)用于將一個(gè)可遍歷的數(shù)據(jù)對(duì)象(如列表、元組或字符串)組合為一個(gè)索引序列,同時(shí)列出數(shù)據(jù)和數(shù)據(jù)下標(biāo),一般用在for循環(huán)當(dāng)中,這篇文章主要介紹了Python基礎(chǔ)之enumerate()函數(shù)用法的相關(guān)資料,需要的朋友可以參考下
    2025-12-12
  • 通過celery異步處理一個(gè)查詢?nèi)蝿?wù)的完整代碼

    通過celery異步處理一個(gè)查詢?nèi)蝿?wù)的完整代碼

    今天小編就為大家分享一篇通過celery異步處理一個(gè)查詢?nèi)蝿?wù)的完整代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • Python?numpy下幾種fft函數(shù)的使用方式

    Python?numpy下幾種fft函數(shù)的使用方式

    numpy中有一個(gè)fft的庫,scipy中也有一個(gè)fftpack的庫,各自都有fft函數(shù),兩者的用法基本是一致的,下面這篇文章主要給大家介紹了關(guān)于Python?numpy下幾種fft函數(shù)的使用方式,需要的朋友可以參考下
    2022-08-08
  • python pands實(shí)現(xiàn)execl轉(zhuǎn)csv 并修改csv指定列的方法

    python pands實(shí)現(xiàn)execl轉(zhuǎn)csv 并修改csv指定列的方法

    今天小編就為大家分享一篇python pands實(shí)現(xiàn)execl轉(zhuǎn)csv 并修改csv指定列的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12

最新評(píng)論

南陵县| 伊吾县| 合肥市| 师宗县| 济南市| 玉溪市| 冀州市| 津南区| 科尔| 民县| 德清县| 抚远县| 隆化县| 东乡族自治县| 元氏县| 宝鸡市| 安塞县| 长武县| 万山特区| 邻水| 昭平县| 响水县| 贵南县| 荆州市| 青浦区| 宾川县| 淮南市| 东丽区| 汕头市| 沧州市| 峨眉山市| 武威市| 邻水| 博野县| 开平市| 敦化市| 布尔津县| 彭山县| 格尔木市| 姚安县| 巍山|