2025-05-12

Selenium Chrome WebDriver 定位 之2

之前在 Selenium Chrome WebDriver 定位 有記錄過 Chrome 模擬定位,但前陣子遇到 CDP 送了定位但沒有用的情況。 

所以我實際使用 Chrome 送一次 CDP command 試試。 

1. 首先,允許網站定位。 
2. 接著在開發者工具中找到 Protocol Monitor(沒有開啟過的話,需要先去 Settings > Experiments > Protocol Monitor 勾選)。 

然後試著在有問題的頁面送 CDP command⋯⋯ 
這時候我發現 Protocol Monitor 有 target 可以選擇;我遇到「送了定位但沒有用」的頁面中有很多 target。

或許是沒有指定時,我 CDP command 沒有送到 main。 

-

看了一下官方文件怎麼指定 target。

1. 先用 Target.getTargets 取得所有 target:
driver.execute_cdp_cmd("Target.getTargets", {})
會得到一個 object。 

2. 拿到你要的 url 的 targetId 之後,attachToTarget 得到 session id:
driver.execute_cdp_cmd("Target.attachToTarget", {
    "targetId": target_id,
    "flatten": True
})
3. 現在就可以送 CDP command 給特定 target 了:
"Emulation.setGeolocationOverride", {
                "latitude": lat,
                "longitude": lng,
                "accuracy": 10,
                "sessionId" : session_id
            }

2025-04-04

自動測試的其他操作元素方式 - 使用 execute_script 執行 JavaScript 操作 DOM

在進行 click、input、scroll 等操作時,有時會遇到元素無法或很難操作的情況。這時可以考慮使用 WebDriver 的 execute_script() 執行 JavaScript 操作 DOM。

以下整理一些常見範例:

選取元素


  • 使用 ID 選取

document.getElementById("example");


  • 使用 class name 選取

document.getElementsByClassName("example");


  • 使用 name 選取

document.getElementsByName("example");


  • 使用 CSS 選取

document.querySelector("[attribute='value1']"); // 選取第一個符合的元素

document.querySelectorAll("input[attribute='value2']"); // 選取所有符合的元素


  • 使用 tag name 選取

document.getElementsByTagName("input"); // 選取所有 input 元素


  • 使用 XPath 選取

document.evaluate("//*[text()='example']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;


操作元素

選取後可進行修改、點擊、滾動等操作。


  • 點擊元素

document.getElementById("example").click();


  • 點擊多個元素中的其中一個

var a = document.getElementsByClassName("ui example button");

a[2].click(); // 選取第三個符合的按鈕並點擊


  • 修改 value 值

document.getElementById("example").value = "20";


修改其他 attribute 的值

  • document.getElementById("Mobility").selectedIndex = 12; // 設定 select 選擇的索引值


  • 移除屬性

document.getElementsByName("example")[0].removeAttribute("hidden"); // 移除 hidden 屬性


  • 捲動元素到視窗可見範圍

arguments[0].scrollIntoView();


  • 捲動元素到視窗中間

arguments[0].scrollIntoView({ block: 'center' });


⋯⋯

總之 JS 有的都可以用。

execute_script  不僅限於不能操作時才用得到,像是想要觀察游標位置等,也可以用 JS 顯示游標的移動。

但 execute_script 並不是真正的操作,所以在以 event 判斷的頁面,可能表面看起來操作成功,但實際上並未觸發預期效果。

2025-03-18

Github Actions cron 排程

之前在 Github Actions 上設定排程的時候,為了測試方便,設定了2分鐘,然後發現過了10幾分鐘都沒有執行。

查了一下才發現,文件上說,workflow 可以執行的最短間隔是5分鐘,而且在負載較高的時候可能會延後,也可能被取消。

設定每5分鐘執行,也會因為負載調整,可能延後到15分鐘才執行。

2025-03-16

Chrome 開發者工具 console 拿 xpath 階層下所有元素的 text

每個人習慣的抓 xpath 的插件不太一樣。
但是假如不想用任何插件,Chrome 的開發人員工具其實很夠用了。
像是大家都知道的,在開發人員工具 > console 中輸入:

  $x("//*[text()='隨便一個範例的 xpath']") 

可以用來確認 xpath 是否有選到元素、選到幾個元素等。

要確認文字也很容易,一般只要「這個」xpath 本身的文字的話,直接看 element 就可以了,但確認的場景可能是想取得這個 xpath 下「所有階層」的文字。
可以像這樣:

$x("xpath").map(el => el.innerText || el.textContent);

至於 innerText 和 textContent 有什麼差異,可能之後再筆記一下。

2025-03-01

[Mac] Python venv 設定

1. 到你想要放 venv 的路徑
2. python venv venv_name 
(看你 python 怎麼裝,可能要 python3 -m venv venv_name)
這樣就有叫 venv_name 的資料夾了
3. source venv_name/bin/activate
就可以使用這個 venv

deactivate可以離開