iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0

! 本篇文章將會介紹 網頁填表實戰:教 Agent 填表格,期望大家都能讓 Agent 在慢網路下也把表格填得又穩又準 :D

d16 收工時,Agent 已經能以「老熟人」的身分喚起瀏覽器——登入這關過了,但登入只是起點,真正的戰場是表格本身。本系列每天 20:00 的發文管線,核心動作說穿了就是「填兩個欄位、按一次送出」,聽起來小學生等級,實際踩下去才發現坑全集中在兩件事上:定址(元素到底怎麼指認)跟時序(什麼時候可以動手)。d15 的測驗埋過一句伏筆:「W3 會花一整天教 selector 跟等待策略」——就是今天。我們拿一張公開的練習表單把招式全部跑過一遍,d19、d20 拆 iThelp 編輯器時直接見真章。

本篇目標

讀完這篇你會學到:

  • 兩種定址模式:snapshot 的 @ref 與 CSS selector,各自的強項、弱項與選用心法
  • 填表操作組合技:fill、click、select 分別對付文字框、單選多選、下拉選單
  • 三級等待策略:從傻等固定秒數到等元素、等網路穩定,慢網路下也填得穩

環境準備

  • d15 裝好的 agent-browser(本系列機器上是 0.34.0)
  • d16 的 ab() 函式:session 與 profile 綁定。練習頁雖然不用登入,紀律照走
  • 一個練習用的公開表單:httpbin.org 的披薩訂單頁,有文字框、單選、多選、下拉、textarea,麻雀雖小五臟俱全
# d16 的綁定函式,本篇沿用
ab() { agent-browser --session ithelp --profile "$HOME/.agent-browser-profiles/ithelp" "$@"; }

主要內容

步驟一:定址——@ref 與 CSS selector 的取捨

指認元素有兩種模式:

  • @ref:snapshot 現場發放的號碼牌。貼近 Agent 的視角、零額外成本,探索階段最好用;缺點是壽命只有一輪,頁面一變全部重洗(d15 的鐵律)。
  • CSS selector:直接寫 input[name='custname'] 這種地址。寫進腳本可以重跑一百次都不必先看頁面;代價是你得先知道地址長怎樣,而且地址本身可能隨時搬家。

選用心法一句話:探索用 @ref,腳本錨點用 selector。先用 snapshot 看清地形,找到真正穩定的元素後(id、name、data-testid 這類語意屬性),寫死進腳本;@ref 留給臨場反應。實際看一下練習頁的地形:

ab open https://httpbin.org/forms/post
ab snapshot -i -s "form"        # 只看表單範圍,輸出精簡(簡化示意)

# @e1  [textbox]  "Customer name"
# @e7  [radio]    "Large"
# @e10 [checkbox] "Bacon"
# @e14 [button]   "Order Pizza"
# 兩種寫法等價;寫進排程腳本建議用第二種,跨 snapshot 穩定
ab fill "@e1" "鐵人 Agent"
ab fill "input[name='custname']" "鐵人 Agent"

那 class 呢?醒醒,現代前端框架的 class 是編譯產物(css-1x2y3z 這種雜湊),下次部署就換一批。拿 class 當腳本錨點,等於把排程腳本綁在流沙上。

步驟二:出手——fill、click、select 的組合技

定址搞定,各類欄位各有一套正確姿勢:

# 文字框:fill 會先清空再填入,重跑安全(d15 老朋友)
ab fill "input[name='custname']" "鐵人 Agent"
ab fill "input[name='custemail']" "agent@example.com"

# 單選/多選:沒有 fill 的份,就是 click
ab click "input[value='large']"    # 大披薩
ab click "input[value='bacon']"    # 加培根

# 下拉選單:用 select 指定 option 的 value(value 以實際頁面為準)
ab select "select[name='delivery']" "18:00"

# 多行文字:textarea 一樣用 fill
ab fill "textarea[name='comments']" "請放門口,謝謝"

兩個細節。第一,fill 跟 type 的分工 d15 提過:fill 清空再填、適合表單;type 是疊打,留給 autocomplete 這種要逐字觸發聯想選單的欄位。第二,click 是切換不是設定——checkbox 已經被勾選時,再 click 一次是「取消勾選」。互動時這是 feature,在會重跑的排程腳本裡是炸彈:腳本重試第二次,培根就被退訂了。保險做法是出手前先驗狀態:

# 已勾選就跳過,讓每個動作可安全重跑(冪等)
ab eval "document.querySelector(\"input[value='bacon']\").checked ? 'CHECKED' : 'NOT_YET'"

小小小測驗:你知道按下送出鈕的那一瞬間,資料其實還沒離開瀏覽器嗎?
答案:click 只是請瀏覽器「開始」送出——表單驗證、JavaScript 前處理、HTTP 請求都還在跑。所以送出後的等待與驗證不可省,不然你驗收的是一個還在半路上的答案。這就帶到今天的第三招。

步驟三:時序——三級等待策略

launchd 在 20:00 叫醒的 headless 瀏覽器,網路狀況沒人看得到。傻等固定秒數是最該淘汰的策略:等太短照樣搶拍、等太長天天浪費壽命。把等待分成三級,按需要取用:

# Level 0:固定傻等——只該出現在「就是想緩一下」的場合
ab wait 500

# Level 1:等元素——等「下一個要操作的那個」出現,日常主力
ab wait "textarea[name='comments']"

# Level 2:等網路——導航或送出之後,等請求潮退掉再動作
ab wait --load networkidle

原則:等你要操作的那個元素,而不是等整頁「感覺」載好了。整組串起來就是一輪完整實戰:

ab open https://httpbin.org/forms/post
ab wait "input[name='custname']"                  # 欄位長出來才動手
ab fill "input[name='custname']" "鐵人 Agent"
ab click "input[value='large']"
ab click "input[value='bacon']"
ab fill "textarea[name='comments']" "請放門口,謝謝"
ab snapshot -i -s "form"                          # 送出前最後一眼,順便領按鈕的 ref
ab click "@e14"                                   # 點「Order Pizza」(ref 以實際 snapshot 為準)
ab wait --load networkidle                        # 等請求潮退
ab get text "pre"                                 # httpbin 會回顯你送出的 JSON,肉眼可驗

最後那個回顯很重要:httpbin 會把你送出的表單內容原封不動印回來,一眼就能核對「培根有沒有上車」。「資料真的被收下」要有證據,這就是最樸素的證據——等 d18 講截圖驗證,會把存證這件事升級成標準配備。

常見問題 / 踩坑記錄

  • Q:selector 昨天能跑、今天失效?
    A:九成是錨點選錯。class 常是框架編譯出來的雜湊,一改版就換;排程腳本的錨點一律挑語意屬性(id、name、data-testid)。真的沒有穩定屬性,就退回「snapshot + @ref」的臨場模式,讓 Agent 每次現場找——慢一點,但活得好好的。
  • Q:fill 明明執行成功,欄位卻是空的?
    A:典型時序問題——fill 當下欄位還在重新渲染,填完就被 SPA 換掉了。解法是出手前先 wait 該元素(Level 1),大型 SPA 再疊 networkidle,確保初始渲染跑完才動筆。
  • Q:腳本重試之後,選項反而被取消勾選?
    A:click 是切換不是設定。重試安全要求每個動作冪等:出手前先用 eval 或 snapshot 確認狀態,已達成就跳過。d12 講重試設計時鋪的哏,在瀏覽器自動化這關又驗收一次。
  • Q:autocomplete 欄位 fill 完,聯想選單還掛著、送出值不對?
    A:這類 widget 要的是「逐字輸入」的事件流。改用 type 逐字打,或 fill 完補個 Escape 讓它收單。表單 widget 千奇百怪,遇到不講理的就截圖看一眼(d18 主角),別盲猜。

小結

  • 定址兩模式:探索用 @ref,腳本錨點用 selector(id/name/data-testid);class 雜湊是流沙,別碰
  • 操作組合技:fill 清空再填對付文字與 textarea,radio/checkbox 用 click 但記得它會切換,下拉用 select
  • 等待三級制:固定傻等 < 等元素 < networkidle,原則是等「下一個要操作的元素」
  • 重跑安全靠冪等:出手前驗狀態,腳本重試才不會把培根退訂

明日預告

下一篇我們要介紹「截圖驗證:眼見為憑的自動化驗收」,今天零星用的 screenshot 要升級成標準配備——每一步存證,讓自動化作業可稽核、可除錯,敬請期待!

參考資料:

有任何疑問但沒有 iT 邦幫忙帳號,或是想匿名提問?
歡迎到 https://dev.benben.me/q/Z5442T 提問或加油打氣,沒意外的話會在完賽之後一起回答 :D


上一篇
16 Persistent profile:登入一次,永久 headless
下一篇
18 截圖驗證:眼見為憑的自動化驗收
系列文
自我耍廢組:全自動化の鐵人 共 19 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言