selenium 非同步 execute script 用法

直接執行 js ,就用 execute_script() 就可以。

從 selenium 的source code 來看,有3種執行script 的方式,其中2個是非同步:
https://github.com/SeleniumHQ/selenium/blob/trunk/py/selenium/webdriver/remote/command.py

W3C_EXECUTE_SCRIPT: str = "w3cExecuteScript"
W3C_EXECUTE_SCRIPT_ASYNC: str = "w3cExecuteScriptAsync"
EXECUTE_ASYNC_SCRIPT: str = "executeAsyncScript"

範例python script

script = """
var callback = arguments[arguments.length - 1]; 
window.setTimeout(function(){ callback('timeout') }, 3000);
"""
driver.execute_async_script(script)

範例2號:

js = """var t = JSON.parse(Cookies.get("user")) ? JSON.parse(Cookies.get("user")).access_token : "";
fetch("%s",{headers: {
authorization: "Bearer ".concat(t)
}}).then(function (response) {
return response.json();
}).then(function (data) {
console.log(data);
if(data.result.product.length>0)
if(data.result.product[0].status=="pending") {
console.log("pending, start to reload");
location.reload();
}
}).catch(function (err){
console.log(err);
});
""" % getSeatsByTicketAreaIdUrl
driver.set_script_timeout(0.1)
driver.execute_async_script(js)

說明:經測試,用使 jQuery 的 ajax 或是使用 fetch 的 promise 都無法在 ajax 傳回的那一個區塊使用下面的程式碼傳回資料:

var callback = arguments[arguments.length - 1];
callback(data);

variable scope 的問題,var callback 才需在 global scope 才可以成功地傳回值,不然 driver.execute_async_script() 的 javascript script 不論怎麼執行都會等到 timeout 也沒資料回傳。


範例3號,常見 OCR 的:

driver.set_script_timeout(1)
form_verifyCode_base64 = driver.execute_async_script("""
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    var img = document.getElementById('%s');
    if(img!=null) {
    canvas.height = img.naturalHeight;
    canvas.width = img.naturalWidth;
    context.drawImage(img, 0, 0);
    callback = arguments[arguments.length - 1];
    callback(canvas.toDataURL()); }
    """ % (image_id))
if not form_verifyCode_base64 is None:
    img_base64 = base64.b64decode(form_verifyCode_base64.split(',')[1])

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *