【问题标题】:Is Selenium slow, or is my code wrong?Selenium 慢,还是我的代码错误?
【发布时间】:2013-07-02 00:31:56
【问题描述】:

所以我尝试使用 Python 登录 Quora,然后抓取一些东西。

我正在使用 Selenium 登录网站。这是我的代码:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()
driver.get('http://www.quora.com/')

username = driver.find_element_by_name('email')
password = driver.find_element_by_name('password')

username.send_keys('email')
password.send_keys('password')
password.send_keys(Keys.RETURN)

driver.close()

现在的问题:

  1. 查找并填写登录表单花了大约 4 分钟,这非常缓慢。我可以做些什么来加快这个过程吗?

  2. 登录后,如何确保没有错误?也就是说,如何查看响应码?

  3. 如何使用 selenium 保存 cookie,以便登录后可以继续抓取?

  4. 如果没有办法让 selenium 更快,还有其他登录方式吗? (Quora 没有 API)

【问题讨论】:

  • 哪些线路耗时?
  • @vincebowdren 几乎所有人。浏览器打开得很好,但随后找到并填写字段大约需要一分钟。
  • @user1177636 是的。在谷歌上工作得很好。一定是quora的问题。
  • 使用 Quora 和最新的 Selenium C# API,对我来说很快。
  • 有多快?因为我已经用 Python API 在 3 台机器上试过了,而且速度太慢了。

标签: python selenium http selenium-webdriver ui-automation


【解决方案1】:

我在使用 ChromeDriver 的 Python selenium 中调用非常慢的 find_elements_xxx 时遇到了类似的问题。我最终找到了我在 find_element_xxx() 调用之前进行的 driver.implicitly_wait() 调用的问题;当我把它拿出来时,我的 find_element_xxx() 调用运行得很快。

现在,我知道当我调用 find_elements_xxx() 时,这些元素就在那里。所以我无法想象为什么implicit_wait 会影响这些操作的速度,但确实如此。

【讨论】:

  • 当我切换到 WebDriverWait 方法并完全忘记了这个调用时,这对我很有帮助。谢谢!
  • 天哪,我不久前把它放进去测试,忘了它在那里。我一直想知道为什么它要花这么长时间才能运行。太多了
  • 在 Protractor 中,我有一个页面突然需要几分钟才能与之交互,可能是由于另一个团队推送的代码中的 JavaScript 异常......我一直在使用 browser.driver.manage() .timeouts().implicitlyWait(10000) 在我的 onPrepare 中没有问题,但是当我把它拿出来时,现在 Selenium 能够有效地与这个页面交互。谢谢@Polly!!!
【解决方案2】:
  1. 我去过那里,硒很慢。填写表格可能不会像 4 分钟那么慢。然后我开始使用 phantomjs,它比 firefox 快得多,因为它是无头的。安装最新的 phantomjs 后,您可以简单地将 Firefox() 替换为 webdriver 行中的 PhantomJS()。

  2. 要检查您是否已登录,您可以断言登录后显示的某些元素。

  3. 只要您不退出驱动程序,cookie 就可用于跟踪链接

  4. 您可以尝试使用 urllib 并直接发布到登录链接。您可以使用 cookiejar 来保存 cookie。你甚至可以简单地保存cookie,毕竟cookie只是http头中的一个字符串

【讨论】:

  • 1. PhantomJS 肯定要快得多(我仍然花了 38 秒)。但我希望能够在切换到无头浏览器之前查看脚本在浏览器中的作用。 2.assert "Home" in driver.title 给了我AssertionError。 4. 我可以试试。
  • 通过他们的网站安装最新版本的 phantomjs,而不是 apt-get。版本应该是 1.9.1
  • 是的,我就是这么做的。从他们的网站下载最新版本,将其放在与我的程序相同的文件夹中,然后出现此错误。我下载的文件是phantonjs(没有扩展名)
  • Karan,您必须将它放在 $PATH 变量中的文件夹中。如果您将它放在当前文件夹中,它可能不起作用,除非您的 $PATH 包含 .
【解决方案3】:

您可以使用自己的 setAttribute 方法来加快表单填写,这里是 java 的代码

public void setAttribute(By locator, String attribute, String value) {
    ((JavascriptExecutor) getDriver()).executeScript("arguments[0].setAttribute('" + attribute
            + "',arguments[1]);",
            getElement(locator),
            value);
}

【讨论】:

  • 你能解释一下它的作用以及它如何使脚本更快吗?
  • 你可以执行 setAttribute(FindBy*****(your locator here), "value", "Text you want to be put in the field); 它会设置 HTML 属性 " value" 到您要填写该字段的文本。基本上 send_keys 操作存在超时,我的方法通过在您的页面中进行 JS 注入以将您的文本分配给该字段来绕过这个,这将非常快地完成。
  • 天哪,超级甜!!!我假设这将通过 browser.execute_script(' // javascript goes here ') 和 python 来完成??
【解决方案4】:

无头运行 Web 驱动程序应该会在一定程度上提高其执行速度。

from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options

options = Options()
options.add_argument('-headless')
browser = webdriver.Firefox(firefox_options=options)

browser.get('https://google.com/')
browser.close()

【讨论】:

    【解决方案5】:

    对于带有 Python Selenium 的 Windows 7 和 IEDRIVER,结束 Windows 命令行并重新启动它可以解决我的问题。

    我遇到了 find_element..clicks 问题。他们花了30秒加上一点点。这是我的代码类型,包括捕获运行多长时间。

    timeStamp = time.time()
    elem = driver.find_element_by_css_selector(clickDown).click()
    print("1 took:",time.time() - timeStamp)
    
    timeStamp = time.time()
    elem = driver.find_element_by_id("cSelect32").click()
    print("2 took:",time.time() - timeStamp)
    

    每次点击记录大约 31 秒。结束命令行并重新启动它(这确实结束了任何 IEDRIVERSERVER.exe 进程)后,每次单击为 1 秒。

    【讨论】:

      【解决方案6】:

      我已经更换了定位器,而且效果很快。此外,我还添加了使用 cookie。检查下面的代码:

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support import expected_conditions as EC
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.common.keys import Keys
      import pickle
      
      
      driver = webdriver.Firefox()
      driver.get('http://www.quora.com/')
      wait = WebDriverWait(driver, 5)
      username = wait.until(EC.presence_of_element_located((By.XPATH, '//div[@class="login"]//input[@name="email"]')))
      password = wait.until(EC.presence_of_element_located((By.XPATH, '//div[@class="login"]//input[@name="password"]')))
      
      username.send_keys('email')
      password.send_keys('password')
      password.send_keys(Keys.RETURN)
      
      wait.until(EC.presence_of_element_located((By.XPATH, '//span[text()="Add Question"]'))) # checking that user logged in
      pickle.dump( driver.get_cookies() , open("cookies.pkl","wb")) # saving cookies
      driver.close()
      

      我们已保存 cookie,现在我们将在新浏览器中应用它们:

      driver = webdriver.Firefox()
      driver.get('http://www.quora.com/')
      cookies = pickle.load(open("cookies.pkl", "rb"))
      for cookie in cookies:
          driver.add_cookie(cookie)
      driver.get('http://www.quora.com/')
      

      希望,这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2011-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多