最近因?yàn)橐粋€(gè)需求,著手開發(fā)一款使用selenium+requests進(jìn)行多線程的測試工具,當(dāng)然還是基于相對(duì)熟悉的python來開發(fā)。由于很久沒寫了,就有很多道理我都懂,一試就出錯(cuò)的問題,前前后后折騰了幾天總算是開發(fā)完了,這里就把期間遇到的問題做一個(gè)記錄,希望可以幫助到有同樣困惑的同學(xué)。
一、服務(wù)器端環(huán)境配置
1. Ubuntu 20.04配置安裝python 3.10并修復(fù)pip
這個(gè)其實(shí)內(nèi)容不是很難,但無奈網(wǎng)上教程抄來抄去,沒有一個(gè)真正講清楚的,在參考了幾個(gè)教程以及實(shí)際測試后,整理操作如下:
目前ubuntu 20.04默認(rèn)的python版本是3.8,所以我們需要先給系統(tǒng)安裝3.10,然后再設(shè)置默認(rèn)python并修復(fù)對(duì)應(yīng)的pip,這里參考了這篇文章:在Ubuntu20.04上安裝Python3.10以及pip,為了方便我就把命令都直接貼出來,經(jīng)過實(shí)際測試是沒有問題的。
# 這里的命令默認(rèn)是root權(quán)限,如果不是請(qǐng)加上sudo運(yùn)行。
# 添加源
apt install software-properties-common
add-apt-repository ppa:deadsnakes/ppa
apt update
# 安裝
apt install python3.10
# 檢查目前系統(tǒng)中的python版本,如果你的系統(tǒng)中默認(rèn)是python3.9或者其他版本,參照替換這里的3.8即可。
ls -l /usr/bin/python*
# 設(shè)置默認(rèn)python版本,路徑可以根據(jù)實(shí)際情況替換,通常不會(huì)變,特別要注意末尾的1和2兩個(gè)數(shù)字別漏了。
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 2
update-alternatives --config python3
# 這個(gè)時(shí)候在終端中運(yùn)行python3就可以看到已經(jīng)切換到了python3.10,如果你想直接使用`python`,可以自行查詢?nèi)绾瓮ㄟ^設(shè)置alias別名來給命令改名,網(wǎng)上教程很多。
# 此時(shí)pip還不是3.10對(duì)應(yīng)的版本,需要進(jìn)行安裝。
apt install python3.10-distutils
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py
python3 get-pip.py --user
# 然后檢查是否安裝成功
pip3 -V
#顯示“pip 22.1 from /usr/local/lib/python3.10/dist-packages/pip (python 3.10)”就是可以了。
# 20230304更新:
# 如果出現(xiàn)pip功能異常或者告警的操作,可以按照提示把新版的pip路徑加到path里面去:
echo 'export PATH=/home/.../bin:$PATH' >>~/.bashrc
source ~/.bashrc
# 這里的...是你自己的實(shí)際路徑,bashrc也是看你的系統(tǒng)用的是什么終端。
2. ubuntu 20.04安裝chrome瀏覽器和webdriver
使用selenium需要使用和瀏覽器對(duì)應(yīng)版本的webdriver,這里我們使用chrome。
# 下載安裝chrome瀏覽器
apt update
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
apt install ./google-chrome-stable_current_amd64.deb
# 如果是蘋果M系列芯片的虛擬機(jī),可以使用以下替代
sudo apt install chromium-browser
# 查看chrome瀏覽器版本,比如這里是“Google Chrome 101.0.4951.64”
google-chrome -version
下載chromedriver,官方目錄鏈接chromedriver
二 、關(guān)于selenium的一些啟動(dòng)參數(shù)的說明
1. 無窗口模式
options.add_argument('--headless')
2. 隱身模式
options.add_argument("--incognito")
3. 無沙箱模式
# 這個(gè)是當(dāng)出現(xiàn)瀏覽器始終卡在“data:,”的時(shí)候使用
options.add_argument("--incognito")
4. 頁面加載策略
# 當(dāng)瀏覽器打開是,默認(rèn)是阻塞的,即需要等待頁面內(nèi)容加載完成,包括DOM、js、css、圖片等等。driver提供了三種加載策略,none、eager、normal。其中eager是只加載完DOM。
options.page_load_strategy = 'eager'
5. 忽略證書不可信的
# 有時(shí)候遇上https證書為不可信的時(shí)候,可以忽略證書的安全檢查。
options.add_argument('--ignore-certificate-errors')
6. 關(guān)于加載等待
# selenium的啟動(dòng)機(jī)制是這樣的,我們可以在打開頁面前設(shè)置等待頁面加載的時(shí)間
# 第一步配置啟動(dòng)參數(shù)
options.add_argument('xxxxxxxx')
# 第二步啟動(dòng)瀏覽器
driver = webdriver.Chrome(chrome_options=options, executable_path=chrome_driver)
# 第三步設(shè)置等待時(shí)間,單位秒
driver.set_page_load_timeout(25)
# 第四步打開url
driver.get("http://xxxxxxxxxxxxxx")
# 這是如果頁面在25秒內(nèi)沒有加載完策略指定的內(nèi)容,就會(huì)報(bào)錯(cuò)timeout,所以別忘了加上try...except...
7. 當(dāng)打開頁面遇上alert框
# 類似401認(rèn)證那種或者其他頁面默認(rèn)彈出來的alert框,需要跳過的話,可以強(qiáng)行確認(rèn),不存在就跳過
try:
driver.switch_to.alert.accept()
except:
pass
8. 關(guān)于selenium使用http還是https
# selenium有點(diǎn)比較麻煩就是你需要自己確定是http還是https,可以用requests來判斷,我用了一個(gè)簡單粗暴的方法
for protocolType in ["http://", "https://"]*3:
driver.get(protocolType + url.strip())
# 兩種協(xié)議各試3遍
9. 關(guān)于判斷網(wǎng)頁是否打開
# 首先這里是用seleniunm打開大量網(wǎng)站,所以沒法使用特定元素來判斷,網(wǎng)上有些教程是用這樣的方法,思路是可以打開就是title,但是實(shí)際上不管能不能打開都有title,打不開的時(shí)候默認(rèn)title就是url。
driver.title
這里我用了一個(gè)判斷的辦法就是,在加載頁面前設(shè)置一個(gè)啟動(dòng)時(shí)間,結(jié)束設(shè)置一個(gè)結(jié)束時(shí)間,如果有標(biāo)題或者是加載時(shí)間在設(shè)置的加載超時(shí)時(shí)間內(nèi),就算是可以打開,雖然不是很嚴(yán)謹(jǐn),但是誤差相對(duì)來說小很多,附上簡單邏輯代碼供參考。文章來源:http://www.zghlxwxcb.cn/news/detail-489930.html
for protocolType in ["http://", "https://"]*3:
start_time = datetime.datetime.now().timestamp() # 瀏覽器啟動(dòng)時(shí)間
try:
driver.get(protocolType + url.strip())
try:
driver.switch_to.alert.accept()
except:
pass
end_time = datetime.datetime.now().timestamp() # 網(wǎng)頁加載完成時(shí)間
if driver.title or end_time - start_time < 23: # 有標(biāo)題或者小于23秒都算可以打開
print("打開成功")
break
else:
print("打開失敗")
except Exception as e:
print("打開失敗")
time.sleep(2)
driver.quit()
三、關(guān)于測試的時(shí)候到底是http還是https
在測試過程中無論是requests還是selenium都面臨著同一個(gè)問題,就是如何判斷網(wǎng)站使用的是http還是https,在實(shí)際開發(fā)過程中,幾乎沒有找到一種通用方法可以百分百覆蓋的成功判斷并打開所有網(wǎng)站,最后我用的策略就是,把所有的情況都試一遍。然后做一個(gè)計(jì)數(shù)器,成功打開加一,否則不加,最后計(jì)數(shù)不為0即為可以打開,雖然看起來有些啰嗦,但是在網(wǎng)絡(luò)環(huán)境穩(wěn)定的情況下效果還不錯(cuò)。文章來源地址http://www.zghlxwxcb.cn/news/detail-489930.html
# 簡單代碼邏輯
requests_method = [request_method.http_head,request_method.https_head,request_method.http_get, request_method.https_get]
success_hit = 0
fail_hit = 0
if r.status_code in success_code:
success_hit += 1
elif r.status_code in fail_code:
fail_hit += 1
到了這里,關(guān)于關(guān)于python+selenium+requests在服務(wù)器端開發(fā)多線程并發(fā)程序踩過的一些坑的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!