
標題無意冒犯,就是覺得這個廣告挺好玩的
上面這張思維導圖喜歡就拿走,反正我也學不了這么多
文章目錄
- 前言
- 歡迎來到我們的圈子
- 接到專案
- 目前成果(2020.11.12)
- 先上一段代碼,云淡風輕
- 代碼解釋
- 第一個坑:find_element_name
- 第二個坑: switch_to_frame()
- cookies繞過登錄驗證,繞進了荒漠
- 迎來轉機
- 成功路前的磕磕碰碰
- 新增成果(2020.11.17)
前言
前期回顧:我要偷偷學Python(第十一天)
上一篇啊,上一篇說這一篇要帶大家玩selenium,那自然是沒錯的,不過這一篇會不一樣一點,這一篇會持續更新,因為這是我前兩天接手的一個專案,雖然不大,但是也還沒寫完,所以寫一個模塊往這一篇里面加一個模塊,
插播一條推送:(如果是小白的話,可以看一下下面這一段)
歡迎來到我們的圈子
我建了一個Python學習答疑群,有興趣的朋友可以了解一下:這是個什么群
群里已經有一千多個小伙伴了哦!!!
直通群的傳送門:傳送門
本系列文默認各位有一定的C或C++基礎,因為我是學了點C++的皮毛之后入手的Python,這里也要感謝齊鋒學長送來的支持,
本系列文默認各位會百度,學習‘模塊’這個模塊的話,還是建議大家有自己的編輯器和編譯器的,上一篇已經給大家做了推薦啦?
我要的不多,點個關注就好啦
然后呢,本系列的目錄嘛,說實話我個人比較傾向于那兩本 Primer Plus,所以就跟著它們的目錄結構吧,
本系列也會著重培養各位的自主動手能力,畢竟我不可能把所有知識點都給你講到,所以自己解決需求的能力就尤為重要,所以我在文中埋得坑請不要把它們看成坑,那是我留給你們的鍛煉機會,請各顯神通,自行解決,
接到專案
前兩天在群里組了個團隊做個小專案,通過問卷收集資料,預計30套問卷,一套一卷共30份,再將問卷資料匯出,做出可視化視圖,再將
生成的可視化圖表做成輪播圖,放到大螢屏上輪播,
需求分析:立項之后,我們就開始分析需求了,
資料用“金資料”收集,誰來填就不用操心了,
這里設計為表單自動生成,自動發放,自動回收,
資料自動匯出,生成可視化圖表,做成輪播圖的樣式,
前面這些都是可以解決的1,不過最后要在大螢屏上展示,目前我能想到的只有投屏,這個過兩天再去請教一下做產品經理的學長吧,
目前成果(2020.11.12)
目前我做完了中間的部分,將專案一分為二,
已完成:
自動登錄“金資料”,回收報表,資料匯出,
接下來重點處決兩個模塊:表單自動生成,表單樣式已經有做產品經理的學長設計好了,自動化技術也是相通的,所以我覺得可以,
資料可視化處理,雖然我是大資料專業的,還是這門課的課代表,但是這個模塊還是交給了我們團隊里的中流砥柱去辦吧,我覺得他們可以,
輪播圖多半也是他們了,我去解決投放的問題,
先上一段代碼,云淡風輕
# 本地Chrome瀏覽器設定方法
from selenium import webdriver #操作瀏覽器所需的包
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC #Xpath導航所需的包
import time #延時所需的包
from selenium.webdriver.chrome.options import Options
class golden_data:
def __init__(self):
options = Options()
#chrome_options.add_argument('--no-sandbox') # 解決DevToolsActivePort檔案不存在的報錯
#options.add_argument('--disable-gpu') # 谷歌檔案提到需要加上這個屬性來規避bug
#options.add_argument('blink-settings=imagesEnabled=false') # 不加載圖片, 提升速度
#options.add_argument('--headless') # 瀏覽器不提供可視化頁面. linux下如果系統不支持可視化不加這潭訓啟動失敗
self.driver = webdriver.Chrome(options=options,executable_path="D:/Python3.9/chromedriver.exe") # 獲取谷歌瀏覽器控制句柄
self.driver.get('https://jinshuju.net/login') # 打開金資料登錄頁面
self.wait = WebDriverWait(self.driver, 10) # Xpath導航
time.sleep(2)
#登錄金資料
def login_data(self):
# 往賬戶欄寫入內容
name_input = self.wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="auth_key"]')))
name_input.clear()
name_input.send_keys('18039027069') # 在這寫入你的姓名
time.sleep(2)
# 點擊“下一步”
next_step = self.wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="login_form"]/div/div[3]/button')))
next_step.click()
time.sleep(2)
# 往密碼欄輸入內容
pwd_input = self.wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="password"]')))
pwd_input.clear()
pwd_input.send_keys('123456.sp') # 在這寫入你的姓名
time.sleep(2)
# 點擊登錄
login_click = self.wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="login_form"]/div/div[4]/button')))
login_click.click()
time.sleep(2)
#創建表單
#def create_table(self):
#收集表單資料
def collect_data(self):
#點擊第一個問卷
first_block = self.wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="5fa54cff61936cdee3121fa5"]/div/a')))
first_block.click()
time.sleep(2)
#點擊‘資料’
table_click = self.wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="entries_nav"]')))
table_click.click()
time.sleep(2)
#資料匯出
data_out = self.wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[3]/div[1]/div[3]/div/div[2]/table/tbody/tr/td[15]')))
data_out.click()
time.sleep(60) #這里的等待時間有點不好控制
#資料預下載
data_fore_download = self.wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="export_job_modal"]/div/div/div[3]/div/a[1]')))
data_fore_download.click()
time.sleep(10)
#資料下載
data_download = self.wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[3]/div[1]/div[3]/div/div[2]/table/tbody/tr/td[15]/table/tbody/tr/td/div[1]/span[2]/a[1]')))
data_download.click()
self.driver.close()
test = golden_data()
test.login_data()
test.collect_data()
別噴,我知道代碼健壯性不行,也知道沒有什么高可用性,但是這只是我作為一個新手一天的成果而已,又不是學不會,后面慢慢就補上了,
崩潰瞬間的圖片我就收走啦,放著一堆圖都不給我推送了,
這篇也重發吧,因為又更新了一大塊
代碼解釋
還記得多少就解釋多少吧,
第一個坑:find_element_name
最開始的時候,我的代碼并不是像上面那套寫的,是這類的:
···
name_in = driver.find_element_by_name('···')
teacher.send_keys('····')
pwd_in = driver.find_element_by_name('···')
assistant.send_keys('····')
time.sleep(1)
button = driver.find_element_by_class_name('···')
time.sleep(1)
button.click()
time.sleep(1)
driver.close()
好家伙,報什么錯呢?
NoSuchFrameException: Message: no such frame
好家伙,我雖然沒有身經百戰,大大小小也數十戰了吧,我果斷的打開了百度,一大堆的解決方案映入眼簾,我會眼花繚亂?會個球,我一眼就抓出了這堆凌亂的解決方案中的共同點,他們都在重復著一個標簽名“ifraem”,哎,不重要,反正就這幾個字母的組合排列,
說什么,是由于存在了標簽頁的切換,所以要先進入到那個標簽頁,只需要把那頁的id或者class提出來做一個引導就好,
吶,像這樣:browser.switch_to_frame('新iframe')
嘿,你還真別說,我還就照做了,這也成了我一晚上崩潰的起點,
第二個坑: switch_to_frame()
哇,這個巨坑,一貼上去這行代碼就顯示被刪掉了,然而我并不這么認為,于是,,,
那么這個是怎么肥四呢?
這個函式確實是被棄用了,在我的不斷努力之下,我找到了替代函式:switch_to.frame()
這個解決了就萬事大吉了?
請繞回第一個問題,
崩潰嗎?當你以為自己正在過關斬將,一路高歌猛進的時候,突然發現自己原來還在原地打轉,
繞來繞去繞不出來,都大晚上的一兩點了,我就果斷的去睡了,
睡之前,我思量再三,明天起來換cookies吧,
cookies繞過登錄驗證,繞進了荒漠
用cookies怎么繞我就不多說了,不會繞的請回到“第七天”開始,
就直接說我繞過去之后得出了個什么玩意兒吧:
D:\pythonProject3\Scripts\python.exe C:/Users/asus/PycharmProjects/pythonProject3/main.py
<Response [200]>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<title>金資料 - 找不到頁面</title>
<meta content="IE=Edge,chrome=1" http-equiv="X-UA-Compatible"/>
<link href="https://gd-assets.jinshujucdn.com/assets/favicon-62fe2f27ea9d532a13fc76ed0e8b5e68bc2f61dde4a7935f54ff5dc3e3a727b2.ico" rel="shortcut icon" type="image/x-icon"/>
<link href="https://gd-assets.jinshujucdn.com/assets/blank-layout-67aac9b8f147aa0bf1d9b85c3683738452c3f41160e169b85e61130171db5992.css" media="screen" rel="stylesheet"/>
</head>
<body>
<div class="main-content blank-container">
<div class="page-alert">
<div class="status-code">404</div>
<h2>對不起,您要找的頁面不存在</h2>
<p>您確定是這個網址嗎?或者<a href="/">回傳首頁</a></p>
</div>
</div>
<footer>
<a class="powered-by" data-no-turbolink="true" href="/">
<p><span>Powered By </span><i class="gd-icon-logo powered-logo"></i><span> 金資料</span></p>
</a> </footer>
<script>
var _hmt = _hmt || [];
(function() {
if(document.querySelectorAll("script[src*='hm.baidu.com']").length === 0){
var hm = document.createElement("script");
hm.src = "//hm.baidu.com/hm.js?47cd03e974df6869353431fe4f4d6b2f";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
}
})();
</script>
</body>
</html>
你知道嗎?當我繞過了登錄驗證的時候,我心里還有一陣竊喜,嘿,小樣兒,還不是讓老子過了,
然后,‘pia’

后來想了想,還是回來用selenium了,
為什么呢?首先肯定是有我的考量的,其次還是有我的考量的,最后是因為專案中的其他模塊還要用到selenium呢,早晚都要面對,早死晚死都得死,
迎來轉機
就在這山窮水盡之時,我抱著試一試的心態,直接搜“selenium操作金資料”,,
死馬當活馬醫了,你們猜怎么著?


果然球都沒查到哈哈哈哈哈
最后,迫于無奈,我又去換了套教程,“selenium自動化測驗操作Chrome”,哎,翻來覆去翻來覆去,找到一個電科大的學長留給他的學弟們的偷懶腳本,我的天,終于幫我開張了(注意,此前我一步都沒邁出去,連UI都摸不到)!!!

于是,就出現了文章開頭那段代碼,
其實那段代碼也不簡單,并不是說改一下就完了,那么簡單的早就搞好了,
成功路前的磕磕碰碰
其實我剛開始并不是寫成這樣的,剛開始我是寫成C語言格式的,雖然我知道現在這個也是C語言風格的,誰要是跟我說這是面向物件,那我勸你回去學一下設計模式吧,
# 本地Chrome瀏覽器設定方法
class golden_data:
def __init__(self):
#這幾行用于隱藏瀏覽器,但是會導致檔案無法下載,所以暫時擱置
#options = Options()
#chrome_options.add_argument('--no-sandbox') # 解決DevToolsActivePort檔案不存在的報錯
#options.add_argument('--disable-gpu') # 谷歌檔案提到需要加上這個屬性來規避bug
#options.add_argument('blink-settings=imagesEnabled=false') # 不加載圖片, 提升速度
#options.add_argument('--headless') # 瀏覽器不提供可視化頁面. linux下如果系統不支持可視化不加這潭訓啟動失敗
獲取句柄,登錄,略過
#收集表單資料
def collect_data(self):
#點擊第一個問卷
這里需要提高可拓展性
first_block = self.wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="5fa54cff61936cdee3121fa5"]/div/a')))
first_block.click()
time.sleep(2)
#點擊‘資料’
table_click = self.wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="entries_nav"]')))
table_click.click() 這里曾經死活點不過去,后來發現是由于復制粘貼之后忘記把first_block改成table_click了
time.sleep(2)
#資料匯出
data_out = self.wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[3]/div[1]/div[3]/div/div[2]/table/tbody/tr/td[15]'))) 這里曾經無法將資料匯出,直接copy Xpath已經無法滿足業務需求了
注(1)
data_out.click()
time.sleep(60) #這里的等待時間有點不好控制
這里曾經在函式寫法改為類寫法的時候出現超時,原因在于那時候我就放了10秒
所以這里的速度就非常之受網路影響,此處應該應try···throw···
#資料預下載
data_fore_download = self.wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="export_job_modal"]/div/div/div[3]/div/a[1]')))
data_fore_download.click()
time.sleep(10)
#資料下載
data_download = self.wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[3]/div[1]/div[3]/div/div[2]/table/tbody/tr/td[15]/table/tbody/tr/td/div[1]/span[2]/a[1]')))
這里問題和上面一樣,無法滿足業務需求,不過有了上面做鋪墊,所以這里解決起來就很快
data_download.click()
self.driver.close()
test = golden_data()
test.login_data()
test.collect_data()
注(1):關于copy Xpath 和 copy full Xpath的差別請看這篇文:https://ihaoge.com/archives/952.html
在我看來,就是copy full Xpath比較穩一些,也不知道是不是Xpath比較快一些嘛,畢竟絕對路徑和相對路徑比起來,相對路徑就是快一些的,
先到這里,其實前面的表單自動生成我也寫的快OK了,不過保留一些懸念,慢慢加進來,對,就是放在這篇,這篇持續更新!!!


新增成果(2020.11.17)
這一周事情太多了,所以寫的不多,五天才寫了一篇博客,
這周把表單自動生成的事情辦了,主要是思想上學到了新東西,代碼見,
from selenium import webdriver #操作瀏覽器所需的包
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC #Xpath導航所需的包
import time #延時所需的包
import openpyxl
#@!!!
#打開一班.xlsx檔案
wb=openpyxl.load_workbook('./一班.xlsx') #打開的Excel檔案還要做進一步的選擇
ws = wb.active
driver = webdriver.Chrome() # 獲取谷歌瀏覽器控制句柄
driver.get('https://jinshuju.net/login') # 打開金資料登錄頁面
wait = WebDriverWait(driver, 10) # Xpath導航
time.sleep(2)
#登錄
name_input = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="auth_key"]')))
name_input.clear()
name_input.send_keys('18039027069') # 在這寫入你的姓名
time.sleep(2)
# 點擊“下一步”
next_step = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="login_form"]/div/div[3]/button')))
next_step.click()
time.sleep(2)
# 往密碼欄輸入內容
pwd_input = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="password"]')))
pwd_input.clear()
pwd_input.send_keys('123456.sp')
time.sleep(2)
# 點擊登錄
login_click = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="login_form"]/div/div[4]/button')))
login_click.click()
time.sleep(2)
#創建表單
create_click = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="create_new"]/a')))
create_click.click()
time.sleep(2)
#創建投票
vote_click = wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[8]/div/div/div[1]/div[2]/div/div/div[3]/div/a')))
vote_click.click()
time.sleep(2)
#從文本檔案創建投票
create_from_txt = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="create_form_modal"]/div/div/div[2]/div[2]/div/div/div[1]/div[2]/div[1]/div/div/a')))
create_from_txt.click()
time.sleep(2)
#表單假標題,繞過監管
vote_title = wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[3]/div[2]/div/div[2]/form/div[1]/div[2]/div[1]/div/div/div/input')))
#vote_title.clear()
vote_title.send_keys('EN') # 在這寫入你的姓名
time.sleep(2)
#繞過監管
test = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="root"]/div/div[2]/form/div[1]/div[2]')))
test.click()
time.sleep(2)
#@!!!
#表單真標題
vote_title = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="root"]/div/div[2]/form/div[1]/div[2]/div[1]/div/div/div/input')))
vote_title.clear()
vote_title.send_keys('TEST') #標題名可自由化
time.sleep(2)
#@!!!
#開始表單生成
for j in range(2):#測驗兩列,所以寫個2,后面可拓展
rows = ws.max_row
more_choose_click = wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[3]/div[2]/div/div[1]/div/div[2]/span[1]/div/div/div[2]/a')))
more_choose_click.click()
time.sleep(2)
cell_value = ws.cell(row=1, column=(j + 1)).value
choose_title = wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="root"]/div/div[3]/div[1]/div[2]/div[1]/div/form/div[1]/div[2]/div/div[1]/div[2]/div/div/input')))
choose_title.clear()
choose_title.send_keys(cell_value)
time.sleep(2)
for i in range(2, rows + 1):
cell_value = ws.cell(row=i, column=(j+1)).value
if i>4:
add_choose_click = wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="root"]/div/div[3]/div[1]/div[2]/div[1]/div/form/div[1]/div[2]/div/div[2]/div/div/div/div[2]/div[1]/div/button')))
add_choose_click.click()
time.sleep(2)
choose_text = wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="root"]/div/div[3]/div[1]/div[2]/div[1]/div/form/div[1]/div[2]/div/div[2]/div/div/div/div[2]/ul/li['+str(i-1)+']/div/div/textarea')))
choose_text.clear()
choose_text.send_keys(cell_value)
time.sleep(2)
keep_vote_click = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="form-setting__save-button"]')))
keep_vote_click.click()
time.sleep(2)
announce_vote_click = wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[2]/div[2]/div[2]/div[3]/a')))
announce_vote_click.click()
time.sleep(2)
adr = driver.find_element(By.ID("published_form_link_in_modal")).get_attribute("value")
里面最主要的有一個:表單標題并不能讓你把“未命名表單”這個欄位洗掉,它被設定為了unset,但是吧,我已經學到了:“那只是規則之內的東西,規則之外的你要自己去想辦法”,于是我繞了一圈,還是把它給辦了,嘿嘿,
規則,只能攔住那些老實人,說真的我也是個老實人,不過慢慢的要變得不老實了,不然太吃虧了,這周就一直在吃虧,還好學長們教我繞過這些所謂的規則,
對了,這段代碼里面還有最后一個點沒有做完,復制到剪貼板的網址還沒提取出來,哪位大哥幫個忙?

接下來還有一個操作Excel的模塊去做一下,剩下的就都是小模塊了,問題不大,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/224841.html
標籤:其他
