18.11 项目:自动填表程序
在所有無聊的任務中,填表是最煩人的。到了現(xiàn)在,在最后一章的項目中,你
將搞定它。假設你在電子表格中有大量的數(shù)據(jù),必須重復將它輸入到另一個應用的表單界面中,沒有實習生幫你完成。盡管有些應用有導入功能,讓你上傳包含信息的電子表格,但有時候似乎沒有其他方法,只好不動腦子地點擊
和輸入幾個小時。讀到了本書的這一章,你“當然”知道會有其他方法。
本項目的表單是 Google ?Docs 表單,你可以在 http://nostarch.com/automatestuff
找到,如圖 18-4 所示。
?總的來說,你的程序應該做到:
? ? ?點擊表單的第一個文本字段。
? ? ?遍歷表單,在每個輸入欄鍵入信息
? ? ?點擊Submit 按鈕。
? ? ?用下一組數(shù)據(jù)重復這個過程。這意味著代碼需要做下列事情:
? ? ?調(diào)用pyautogui.click() 函數(shù),點擊表單和 Submit 按鈕。
? ? ?調(diào)用pyautogui.typewrite() 函數(shù),在輸入欄輸入文本。
? ? ?處理 KeyboardInterrupt 異常,這樣用戶能按 Ctrl-C 鍵退出。打開一個新的文件編輯器窗口,將它保存為 formFiller.py。
第 1 步:弄清楚步驟
在編寫代碼之前,你需要弄清楚填寫一次表格時,需要的準確擊鍵和鼠標點擊。
18.4 節(jié)中的 mouseNow.py 腳本可以幫助你弄清楚確切的鼠標坐標。你只需要知道第一個文本輸入欄的坐標。在點擊第一個輸入欄之后,你可以Tab?
鍵,將焦點移到下一個輸入欄。這讓你不必弄清楚每一個輸入欄的 x、y 坐標。
下面是在表單中輸入數(shù)據(jù)的步驟:
1.點擊 Name 輸入欄(在將瀏覽器窗口最大化后,用 mouseNow.py 程序來確定坐標。在 OS X 上,可能需要點擊兩次:一次讓瀏覽器獲得焦點,第二次讓 Name輸入欄獲得焦點)。
2.鍵入名稱,然后按 Tab 鍵。
3.鍵入最大的恐懼(greatest fear),然后按 Tab 鍵。
4.按向下鍵適當?shù)拇螖?shù),選擇魔力源(wizard power source):一次是 Wand,兩次是 Amulet,三次是 Crystal ball,四次是 money。然后按 Tab?
鍵(請注意,在 OS X中,你必須為每次選擇多按一次向下鍵。對于某些瀏覽器,你也需要按回車鍵)。
5.按向右鍵,選擇 RoboCop 問題的答案。按一次是 2,兩次是 3,三次是 4,四次是 5,或按空格鍵選擇 1(它是默認加亮的)。然后按 Tab 鍵。
6.鍵入附加的備注,然后按 Tab 鍵。
7.按回車鍵,點擊“Submit”按鈕。
8.在提交表單后,瀏覽器將轉到一個頁面。然后你需要點擊一個鏈接,返回到表單頁面。
請注意,如果你稍后再次運行這個程序,可能需要更新鼠標點擊的坐標,因為瀏覽器窗口可能已經(jīng)改變了位置。要避免這一點,請一直確保瀏覽器窗口最大化,然后再尋找第一個表單輸入框的坐標。而且,不同操作系統(tǒng)上的不同
瀏覽器,工作起來可能與這里的步驟稍有不同,所以在運行程序之前,要確保這些擊鍵組合適合你的計算機。
第 2 步:建立坐標
在瀏覽器中載入示例表單(圖 18-4),并將瀏覽器窗口最大化。打開一個新的終端窗口或命令行窗口,來運行 mouseNow.py 腳本,然后將鼠標放在輸入框上,弄清楚它的 x、y?
坐標。這些數(shù)字將賦給程序中的變量。同時,找出藍色Submit 按鈕的 x、y 坐標和 RBG 值。這些值將分別賦給變量 submitButton 和 submitButtonColor。
接下來,在表單中填入一些假的數(shù)據(jù),點擊Submit。你需要看到下一個頁面的樣子,
以便使用程序mouseNow.py 尋找這個頁面中Submit another response 鏈接的坐標。
讓你的源代碼看起來像下面的樣子。確保用自己測試得到的坐標代替斜體的值:
#! ?python3
# ?formFiller.py ?- ?Automatically ?fills ?in ?the ?form. import ?pyautogui, ?time
# ?Set ?these ?to ?the ?correct ?coordinates ?for ?your ?computer. nameField ?= ?(648, ?319)
submitButton ?= ?(651, ?817)
submitButtonColor ?= ?(75, ?141, ?249)
submitAnotherLink ?= ?(760, ?224)
# ?TODO: ?Give ?the ?user ?a ?chance ?to ?kill ?the ?script. # ?TODO: ?Wait ?until ?the ?form ?page?
?has ?loaded.
# ?TODO: ?Fill ?out ?the ?Name ?Field.
# ?TODO: ?Fill ?out ?the ?Greatest ?Fear(s) ?field.
# ?TODO: ?Fill ?out ?the ?Source ?of ?Wizard ?Powers ?field. # ?TODO: ?Fill ?out ?the ?RoboCop ?
field.
# ?TODO: ?Fill ?out ?the ?Additional ?Comments ?field.
# ?TODO: ?Click ?Submit.
# ?TODO: ?Wait ?until ?form ?page ?has ?loaded.
# ?TODO: ?Click ?the ?Submit ?another ?response ?link.
現(xiàn)在你需要實際想要輸入這張表格的數(shù)據(jù)。在真實世界中,這些數(shù)據(jù)可能來自電子表格、純文本文件或某個網(wǎng)站。可能需要額外的代碼,將數(shù)據(jù)加載到程序中。但對于這個項目,只需要將這些數(shù)據(jù)硬編碼給一個變量。在程序中加
入以下代碼:
#! ?python3
# ?formFiller.py ?- ?Automatically ?fills ?in ?the ?form.
--snip--
formData ?= ?[{'name': ?'Alice', ?'fear': ?'eavesdroppers', ?'source': ?'wand', 'robocop': ?4, ?
'comments': ?'Tell ?Bob ?I ?said ?hi.'},
{'name': ?'Bob', ?'fear': ?'bees', ?'source': ?'amulet', ?'robocop': ?4, 'comments': ?'n/a'},
{'name': ?'Carol', ?'fear': ?'puppets', ?'source': ?'crystal ?ball', 'robocop': ?1, ?'comments': ?
'Please ?take ?the ?puppets ?out ?of ?the break ?room.'},
{'name': ?'Alex ?Murphy', ?'fear': ?'ED-209', ?'source': ?'money', 'robocop': ?5, ?'comments': ?
'Protect ?the ?innocent. ?Serve ?the ?public trust. ?Uphold ?the ?law.'},
]
--snip--
formData 列表包含 4 個字典,針對 4 個不同的名字。每個字典都有文本字段的
名字作為鍵,響應作為值。最后一點準備是設置 pyautogui 的 PAUSE 變量,在每次函數(shù)調(diào)用后等待半秒鐘。在程序的 formData 賦值語句后,添加下面的代碼:
pyautogui.PAUSE ?= ?0.5
第 3 步:開始鍵入數(shù)據(jù)
for ?循環(huán)將迭代 formData ?列表中的每個字典,將字典中的值傳遞給 pyautogui
函數(shù),最后在文本輸入?yún)^(qū)輸入。在程序中添加以下代碼:
#! ?python3
# ?formFiller.py ?- ?Automatically ?fills ?in ?the ?form.
--snip--
for ?person ?in ?formData:
# ?Give ?the ?user ?a ?chance ?to ?kill ?the ?script.
print('>>> ?5 ?SECOND ?PAUSE ?TO ?LET ?USER ?PRESS ?CTRL-C ?<<<')
? ? ? ? ? ? ?time.sleep(5)
# ?Wait ?until ?the ?form ?page ?has ?loaded.
? ? ? ? ? ? ?while ?not ?pyautogui.pixelMatchesColor(submitButton[0], ?submitButton[1],?
submitButtonColor):
time.sleep(0.5)
--snip--
作為一個小的安全功能,該腳本有 5 秒暫停?。如果發(fā)現(xiàn)程序在做一些預期之外的事, 這讓用戶有機會按 Ctrl-C ( 或將鼠標移到屏幕的左上角, 觸發(fā)?
FailSafeException ?異常),從而關閉程序。然后程序等待,直到 Submit 按鈕的顏色可見?,這讓程序知道,表單頁面已經(jīng)加載了。回憶一下,你在第 2?
步中已經(jīng)弄清楚了坐標和顏色信息,并將它們保存在submitButton 和submitButtonColor 變量中。要調(diào)用 pixelMatchesColor(),就傳遞坐標?
submitButton[0] 和 submitButton[1],以及顏色 submitButtonColor。
在等待 Submit 按鈕顏色可見的代碼之后,添加以下代碼:
#! ?python3
# ?formFiller.py ?- ?Automatically ?fills ?in ?the ?form.
--snip--
? ? ? ? ? ? ?print('Entering ?%s ?info...' ?% ?(person['name']))
? ? ? ? ? ? ?pyautogui.click(nameField[0], ?nameField[1])
# ?Fill ?out ?the ?Name ?field.
? ? ? ? ? ? ?pyautogui.typewrite(person['name'] ?+ ?'\t')
# ?Fill ?out ?the ?Greatest ?Fear(s) ?field.
? ? ? ? ? ? ?pyautogui.typewrite(person['fear'] ?+ ?'\t')
--snip--
我們添加了偶爾的 print() 調(diào)用,在終端窗口中顯示程序的狀態(tài),讓用戶知道進展。?
既然程序知道表格已經(jīng)加載,就可以調(diào)用 click(),點擊 Name 輸入框?,并調(diào)用 typewrite(),輸入 person['name']?
中的字符串?。字符串末尾加上了 '\t' 字符,模擬
按下Tab 鍵,它將輸入焦點轉向下一個輸入框,Greatest Fea(r ?s)。另一次typewrite() 調(diào)
用,將在這個輸入框中輸入 person['fear'] 中的字符串,然后用 Tab 跳到表格的下一個輸入框?。
第 4 步:處理選擇列表和單選按鈕
“wizard ?powers”問題的下拉菜單和RoboCop 字段的單選按鈕,處理起來比文本輸入框需要更多技巧。要用鼠標點選這些選項,你必須搞清楚每個可能選項的 x、 y?
坐標。然而,用箭頭鍵來選擇會比較容易。
在程序中加入以下代碼:
#! ?python3
# ?formFiller.py ?- ?Automatically ?fills ?in ?the ?form.
--snip--
# ?Fill ?out ?the ?Source ?of ?Wizard ?Powers ?field.
? ? ? ? ? ? ?if ?person['source'] ?== ?'wand':
? ? ? ? ? ? ? ? ? ? ? ?pyautogui.typewrite(['down', ?'\t']) elif ?person['source'] ?== ?
'amulet':
pyautogui.typewrite(['down', ?'down', ?'\t']) elif ?person['source'] ?== ?'crystal ?ball':
pyautogui.typewrite(['down', ?'down', ?'down', ?'\t']) elif ?person['source'] ?== ?'money':
pyautogui.typewrite(['down', ?'down', ?'down', ?'down', ?'\t'])
# ?Fill ?out ?the ?RoboCop ?field.
? ? ? ? ? ? ?if ?person['robocop'] ?== ?1:
? ? ? ? ? ? ? ? ? ? ? ?pyautogui.typewrite([' ?', ?'\t']) elif ?person['robocop'] ?== ?
2:
pyautogui.typewrite(['right', ?'\t']) elif ?person['robocop'] ?== ?3:
pyautogui.typewrite(['right', ?'right', ?'\t']) elif ?person['robocop'] ?== ?4:
pyautogui.typewrite(['right', ?'right', ?'right', ?'\t']) elif ?person['robocop'] ?== ?5:
pyautogui.typewrite(['right', ?'right', ?'right', ?'right', ?'\t'])
--snip--
在下拉菜單獲得焦點后(回憶一下,你寫了代碼,在填充 Greatest Fear(s)輸入框后模擬了按 Tab 鍵),按下向下箭頭,就會移動到選擇列表的下一項。根據(jù) person['source']?
中的值,你的程序應該發(fā)出幾次向下按鍵,然后再切換到下一個輸入?yún)^(qū)。如果這個用戶詞典中的 'source' 值是 'wand' ?,我們模擬按向下鍵一次(選擇 Wand),并按?
Tab ?鍵?。如果 'source' 鍵的值是 'amulet',模擬按向下鍵兩次,并按
Tab 鍵。對其他可能的值也是類似。
RoboCop 問題的單選按鈕,可以用向右鍵來選擇?;蛘?#xff0c;如果你想選擇第一個選項?,就按空格鍵?。
第 5 步:提交表單并等待
可以用函數(shù) typewrite() 填寫備注輸入框,將 person['comments'] 作為參數(shù)。你可以另外輸入'\t',將焦點移到下一個輸入框或 Submit 按鈕。當Submit?
按鈕獲得焦點后,調(diào)用 pyautogui.press('enter'),模擬按下回車鍵,提交表單。在提交表單之后,程序將等待 5 秒,等下一頁加載。
在新頁面加載之后,它會有一個 Submit another response 鏈接,讓瀏覽器轉向一個新的、全空的表單頁面。在第二步,你已將這個鏈接的坐標作為元組保存在?
submitAnotherLink 中,所以將這些坐標傳遞給 pyautogui.click(),點擊這個鏈接。
新的表單準備好后,腳本的外層 for 循環(huán)將繼續(xù)下一次迭代,在表單中輸入下一個人的信息。
添加以下代碼,完成你的程序:
#! ?python3
# ?formFiller.py ?- ?Automatically ?fills ?in ?the ?form.
--snip--
# ?Fill ?out ?the ?Additional ?Comments ?field. pyautogui.typewrite(person['comments'] ?+ ?'\t')
# ?Click ?Submit. pyautogui.press('enter')
# ?Wait ?until ?form ?page ?has ?loaded. print('Clicked ?Submit.') time.sleep(5)
# ?Click ?the ?Submit ?another ?response ?link. pyautogui.click(submitAnotherLink[0], ?
submitAnotherLink[1])
在主 for 循環(huán)完成后,程序應該已經(jīng)插入了每個人的信息。在這個例子中,只有 4 個人要輸入。但如果有 4000 個人,那么編程來完成這個任務將節(jié)省大量的輸入時間。
?
總結
以上是生活随笔為你收集整理的18.11 项目:自动填表程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 川希:互联网创业赚钱就是抄抄抄,越抄越
- 下一篇: sql 的 desc和asc用法