python+selenium實作自動化連接校園網(資源下載鏈接在總結)
校園網的自動連接
在學校里面,我經常會用到校園WiFi,我個人使用的是辦移動套餐送的wifi套餐,因此,我連接的WiFi是NJUPT-CMCC,當我寫出來這個代碼的時候,我發給我舍友,他們都說直接用chrome就可以實作記住賬號密碼,點一下就可以實作了登錄,為什么還要特意使用一個程式占記憶體呢?
不知道是不是只有我一個人遇到過這種情況,我在連接NJUPT-CMCC的時候,會隨機出現三個頁面——上網登錄窗、資訊頁、認證成功頁,有的時候我是可以一次登陸成功,但是更多的是出現資訊頁,在這個頁面我還得回傳一次,再去登陸一次,我就很煩!所以,我就寫了這個代碼,僅供參考,本文的內容全部是基于該背景來分享,
多個頁面的識別與判斷
頁面分為三個——上網登錄窗、資訊頁、認證成功頁,
這三個頁面的識別一開始我使用的是selenium的CSS選擇器去進行識別的,后來在別的貼子發現可以直接使用title,但我的代碼里面還是沿用CSS選擇器,因為作用都一樣,
page_information = driver.find_element_by_css_selector('head > title').get_attribute('textContent')
獲取了頁面title之后,開始對title進行全字符匹配判別
#back()表示遇到資訊頁的方法
#quit()表示遇到認證成功頁的方法
if page_information == '上網登錄窗':
pass
elif page_information == '資訊頁':
back()
elif page_information == '認證成功頁':
quit()
#最后無論是哪個頁面,還是得進行登錄操作,
login(account, password)
login()
先上代碼
def login(account, password):
print(account, password)
input_account = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#edit_body > div.edit_row.ui-resizable-autohide > div.edit_loginBox.ui-resizable-autohide > form > input:nth-child(3)')))
input_password = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#edit_body > div.edit_row.ui-resizable-autohide > div.edit_loginBox.ui-resizable-autohide > form > input:nth-child(4)')))
button = driver.find_element_by_css_selector('#edit_body > div.edit_row.ui-resizable-autohide > div.edit_loginBox.ui-resizable-autohide > form > input:nth-child(2)')
input_account[0].send_keys(account)
input_password[0].send_keys(password)
print("準備點擊")
button.click()
(里面的一些print是為了讓我方便進行除錯而用的,對代碼運行沒有影響,)
selenium去獲取上網登錄窗頁面上的兩個文本框,還有登錄按鈕都是用的CSSselector,然后對這兩個文本框進行輸入account&password,
back()
def back():
button_back = driver.find_element_by_css_selector('#edit_body > div > div.edit_loginBox.ui-resizable-autohide > form > input')
button_back.click()
在遇到資訊頁的時候的處理方法很簡單,獲取了回傳按鈕之后就回傳上網登錄窗頁面,
quit()
def quit():
button_quit = driver.find_element_by_css_selector('#edit_body > div > div.edit_loginBox.ui-resizable-autohide > form > input')
button_quit.click()
time.sleep(2)
confirm = driver.switch_to.alert
confirm.accept()
print('你剛剛確認下線')
time.sleep(5)
confirm.accept()
print('現在回傳上網登錄窗頁面')
如果代碼剛開始運行的時候檢測到是在認證成功頁(但是沒網),那就會呼叫到quit的方法,通過這個去注銷賬號密碼,回到上網登錄窗頁面,再進行login,
這個視窗回傳的程序中涉及到彈出兩個提示框,這兩個是這段代碼新的內容,涉及到alert的陳述句就是用來處理這個的,至于等待時間,我在這里使用的是固定時間,與前面使用的自動判斷時間不一樣,
是否成功登陸了呢?
def Is_OK():
#判斷跳轉界面
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
page_information = driver.find_element_by_css_selector('head > title').get_attribute('textContent')
if page_information == '認證成功頁':
print("login successfully")
else:
print("出現資訊頁,正在回傳準備重新登錄")
back()
login(account, password)
這段代碼是在登陸完成之后去檢查是否完成了登錄,檢查原理還是一樣,去識別不同頁面的title,在代碼中我呼叫了兩次這個方法,進行二次認證,
但是,在這里會出現一個問題,就是兩次認證都失敗的話程式還是會照常結束,遇到這種情況的話就是用戶自己輸入的賬號密碼出錯了,但我在這里沒有設定這點,所以如果大家使用出現這種情況的話,一定要檢查自己的賬號密碼是不是錯了:檢查的方法可以是自己去查看同路徑下的txt檔案,然后可以選擇修改檔案內容也可以直接洗掉檔案在下一次運行程式的時候重新輸入賬號密碼,
本地保存賬號密碼
在這里,我選擇的是將賬號密碼保存在本地的同路徑的一個txt檔案內,然后,每一次都會自動去檢查該檔案是否存在,不存在的話會提示用戶重新輸入賬號密碼并保存一份新的檔案,所以大家千萬不要洗掉該txt檔案或者更改名字,另外就是,這份檔案只能儲存一個人的賬號密碼資訊,因為想到畢竟是個人電腦使用的情況較多,而且這么做頁簡單很多,
def txt_handle():
global account, password
try:
f = open('校園網登錄資訊檔案.txt', "r", encoding="utf-8")
lines = f.readlines()
print("已進入")
account = lines[0]
account = account.replace('\n', '')
password = lines[1]
f.close()
print(account, password)
except Exception as e:
account = input("請輸入賬號:")
password = input("請輸入密碼:")
txt = account + '\n' + password
print(account, password)
f = open('校園網登錄資訊檔案.txt', "w+", encoding="utf-8")
f.write(txt)
print("檔案資訊已寫入,請勿洗掉該檔案!")
f.close()
return account, password
全部代碼
#login_selenium.py
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
import time, os
'''
NJUPT-CMCC/ChinaNet自動登錄代碼
author:海hong
本功能主要實作了對于登陸頁面三個視窗的識別以及賬號密碼保存在本地的功能,
通過第一次登陸需要輸入賬號密碼,以后登錄就是一鍵便可完成,時間也很快,目前測驗暫時沒見bug,
'''
def txt_handle():
global account, password
try:
f = open('校園網登錄資訊檔案.txt', "r", encoding="utf-8")
lines = f.readlines()
print("已進入")
account = lines[0]
account = account.replace('\n', '')
password = lines[1]
f.close()
print(account, password)
except Exception as e:
account = input("請輸入賬號:")
password = input("請輸入密碼:")
txt = account + '\n' + password
print(account, password)
f = open('校園網登錄資訊檔案.txt', "w+", encoding="utf-8")
f.write(txt)
print("檔案資訊已寫入,請勿洗掉該檔案!")
f.close()
return account, password
def login(account, password):
print(account, password)
input_account = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#edit_body > div.edit_row.ui-resizable-autohide > div.edit_loginBox.ui-resizable-autohide > form > input:nth-child(3)')))
input_password = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#edit_body > div.edit_row.ui-resizable-autohide > div.edit_loginBox.ui-resizable-autohide > form > input:nth-child(4)')))
button = driver.find_element_by_css_selector('#edit_body > div.edit_row.ui-resizable-autohide > div.edit_loginBox.ui-resizable-autohide > form > input:nth-child(2)')
input_account[0].send_keys(account)
input_password[0].send_keys(password)
print("準備點擊")
button.click()
def back():
button_back = driver.find_element_by_css_selector('#edit_body > div > div.edit_loginBox.ui-resizable-autohide > form > input')
button_back.click()
def quit():
button_quit = driver.find_element_by_css_selector('#edit_body > div > div.edit_loginBox.ui-resizable-autohide > form > input')
button_quit.click()
time.sleep(2)
confirm = driver.switch_to.alert
confirm.accept()
print('你剛剛確認下線')
time.sleep(5)
confirm.accept()
print('現在回傳上網登錄窗頁面')
def Is_OK():
#判斷跳轉界面
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
page_information = driver.find_element_by_css_selector('head > title').get_attribute('textContent')
if page_information == '認證成功頁':
print("login successfully")
else:
print("出現資訊頁,正在回傳準備重新登錄")
back()
login(account, password)
def Is_page():
#判斷跳轉界面
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
page_information = driver.find_element_by_css_selector('head > title').get_attribute('textContent')
if page_information == '上網登錄窗':
pass
elif page_information == '資訊頁':
back()
elif page_information == '認證成功頁':
quit()
login(account, password)
#檢測頁面是否跳轉到認證成功頁
Is_OK()
print("通過第一次驗證")
Is_OK()
print("通過第二次驗證,成功登錄")
url = 'http://p.njupt.edu.cn'
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
driver.get(url)
account = 'XXXXXXXXXX'
password = 'XXXXXX'
txt_handle()
print(account, password)
Is_page()
driver.close()
#print("5秒后視窗自動關閉")
#time.sleep(5)
#os.sys.exit()
注意事項——chromedriver
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
driver.get(url)
第一行代碼,我是之前就已經在chrome的安裝目錄下放置了chromedriver.exe,因此我這里可以直接參考;如果你是第一次接觸到chrome driver,那么你得去下載一個匹配自己chrome版本的driver(一定要是版本匹配),推薦到國內鏡像網站下載,關于看自己chrome的版本可以在地址欄輸入chrome://version/來查看(圖中紅框位置)

如果,你下載下來的chromedriver沒有放置在chrome的安裝路徑下,放在與該代碼同一個檔案夾下,那么,你需要將第一條陳述句改成成:
driver = webdriver.Chrome('chromedriver.exe')
這樣下來,代碼運行應該是沒有很大的問題了,
問題修改
Q1:運行完代碼后,CMD視窗不能自動退出,
driver.close()
#更改上條陳述句為下面:
driver.quit()
Q2:關于自動登陸的驗證
具體內容請看我下一篇文章
Q3:關于開機自啟問題
具體內容可以看CSDN上另一個博主的文章python+windows任務計劃程式實作每日定時登錄校園網,我在它的基礎上進行了任務計劃程式的修改,我修改成了每次登陸時,于是我電腦桌面現在也不用保留這個txt以及py的檔案,除了開機之后桌面會出現大黑框10秒左右之外,真正給我帶來了類似我自己在家上網的舒服度——開機即有網,
總結
代碼不難,但是需要生成exe檔案去服務大眾還是有一定的距離,對方的電腦上如果沒有python、chrome driver環境的話好像是運行不了,但這個對于電腦上有python的人來說就有幫助,起碼減少了許多的麻煩,
文章中我提到的那個小bug,我在Java上面已經修復了,只是不想再改動一次python的代碼了,關于Java的代碼,預計也是在這兩三天我會再寫一篇文章發上來,上面使用到的方法跟這個有不一樣的地方,還是挺有趣的,希望大家到時留心關注我的下一篇博客,
關于python的這部分代碼,我從最初的50行解決自身筆記本上網問題,到后來一點點問題去修改,寫到了現在的近150行,可以說,一般情況下會出現的問題我里面都會有相應的處理機制,但是限于水平有限,有的部分問題還是只能靠人工去判斷(比如深夜斷網、賬號密碼出錯),
關于兼容性問題,我這次做了妥協,本來想的是自動判斷電腦上使用的是哪一款瀏覽器,我就自動匹配相應的driver,但是發現這樣下來的話,大家需要下載的檔案太大,還不如就統一標準,大家都用chrome,這樣是種更加省事的方式,
這次代碼我是打包成了exe檔案,大家的電腦上沒有安裝python、selenium的都是可以正常使用的,具體下載鏈接我將會放在我的百度網盤上,以供大家使用,
百度網盤鏈接
如果有疑問,歡迎大家在下面留言,我看到的話都會盡快回復的,
參考過的博客
1
2
3
4
5
自己曾經用requests寫的自動登錄腳本(涉及到一些沒有說到的基礎問題)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/229462.html
標籤:python
