0

以下脚本在我的机器上花费了 20 多秒:

import selenium.webdriver
import tempfile

def run_webdriver(url):
    with selenium.webdriver.Firefox() as driver:
        driver.get(url)
        button = driver.find_element_by_tag_name('button')
        for i in range(100):
            button.click()

def main():
    with tempfile.NamedTemporaryFile(suffix='.html') as f:
        f.write(b'<!DOCTYPE html><title>x</title><button>x</button>')
        f.flush()
        run_webdriver('file://' + f.name)

if __name__ == '__main__':
    main()

cProfile显示瓶颈在click等待 GeckoDriver。

      100    0.001    0.000   22.101    0.221 webelement.py:78(click)
      105   24.073    0.229   24.073    0.229 {method 'recv_into' of '_socket.socket' objects}

GeckoDriver 日志显示 Marionette 需要 200 毫秒来执行每个WebDriver:ElementClick

$ awk '/Marionette.*->/{ start = $1; request = $6; } /Marionette.*<-/{ print($1 - start, request, $6);  }' geckodriver.log | head
15 [0,1,"WebDriver:NewSession",{"acceptInsecureCerts":true,"browserName":"firefox"}] [1,1,null,{"sessionId":"ef9259e3-8f12-4cc2-a6e1-66846e7b4b77","capabilities":{"browserName":"firefox","browserVersion":"93.0"
248 [0,2,"WebDriver:Navigate",{"url":"file:///tmp/tmp_o5arvre.html"}] [1,2,null,{"value":null}]
10 [0,3,"WebDriver:FindElement",{"using":"css [1,3,null,{"value":{"element-6066-11e4-a52e-4f735466cecf":"73ed82bf-391a-4e62-98b3-7a6a260e3843"}}]
214 [0,4,"WebDriver:ElementClick",{"id":"73ed82bf-391a-4e62-98b3-7a6a260e3843"}] [1,4,null,{"value":null}]
207 [0,5,"WebDriver:ElementClick",{"id":"73ed82bf-391a-4e62-98b3-7a6a260e3843"}] [1,5,null,{"value":null}]
208 [0,6,"WebDriver:ElementClick",{"id":"73ed82bf-391a-4e62-98b3-7a6a260e3843"}] [1,6,null,{"value":null}]
207 [0,7,"WebDriver:ElementClick",{"id":"73ed82bf-391a-4e62-98b3-7a6a260e3843"}] [1,7,null,{"value":null}]
213 [0,8,"WebDriver:ElementClick",{"id":"73ed82bf-391a-4e62-98b3-7a6a260e3843"}] [1,8,null,{"value":null}]
207 [0,9,"WebDriver:ElementClick",{"id":"73ed82bf-391a-4e62-98b3-7a6a260e3843"}] [1,9,null,{"value":null}]
208 [0,10,"WebDriver:ElementClick",{"id":"73ed82bf-391a-4e62-98b3-7a6a260e3843"}] [1,10,null,{"value":null}]

为什么 ElementClick 需要 200 毫秒?可以提速吗?

环境:

  • Arch Linux
  • 摇摆1:1.6.1-1
  • 火狐 93.0-1
  • 壁虎司机 0.30.0-1
  • 蟒蛇硒3.141.0-3
  • 蟒蛇 3.9.7-1
4

1 回答 1

0

ElementClick 应该等待导航完成1。不幸的是,这是在 Marionette 中通过等待 200 毫秒来检查 beforeunload 事件2来实现的。

target=_blank一种解决方法是向按钮34添加属性,即使它不是<a>. 例如:

def run_webdriver(url):
    with selenium.webdriver.Firefox() as driver:
        driver.get(url)
        driver.execute_script('''
          document.querySelectorAll('button').forEach(
            (element) => element.setAttribute('target', '_blank'));
        ''')
        button = driver.find_element_by_tag_name('button')
        for i in range(100):
            button.click()

该脚本现在只需 5 秒。

于 2021-10-23T12:47:49.170 回答