【问题标题】:Python script runs in console but errors out as a scriptPython 脚本在控制台中运行,但作为脚本出错
【发布时间】:2017-12-29 05:34:24
【问题描述】:

我正在编写一个脚本,以从我必须登录才能使用的站点中提取一些信息。我正在使用 Python 2.7.12 和 Selenium 3.4.3。

#!/usr/bin/python
from selenium import webdriver
browser = webdriver.Firefox(firefox_binary='/usr/bin/firefox', executable_path="./geckodriver")

# Get to the login page
browser.get('https://example.com')
browser.find_element_by_link_text('Application').click()

# Login
browser.find_element_by_id('username').send_keys('notmyusername')
browser.find_element_by_id('password').send_keys('notmypassword')
browser.find_element_by_css_selector('.btn').click()

# Open the application
browser.find_element_by_id('ctl00_Banner1_ModuleList_ctl01_lnkModule').click()

如果我复制这段代码并将其粘贴到 python 控制台中,它会运行良好并转到我想要的页面。但是,当我从终端(Linux Mint 18 上的 bash)运行脚本时,它会出错。这是删除了 try 和 catch 语句的输出:

Traceback (most recent call last):
  File "./script.py", line 14, in <module>
    browser.find_element_by_id('ctl00_Banner1_ModuleList_ctl01_lnkModule').click()
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 289, in find_element_by_id
    return self.find_element(by=By.ID, value=id_)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 791, in find_element
    'value': value})['value']
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 256, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="ctl00_Banner1_ModuleList_ctl01_lnkModule"]

我什至不知道如何解决这个问题。有什么帮助吗?

【问题讨论】:

  • 你试过等待吗?
  • @muraliselenium 你的意思是在脚本中等待吗? Selenium 似乎要等到页面加载完毕后再采取任何行动。脚本在无法通过 id 找到元素后出错并停止运行。
  • 是的,你说得对。但有时 thread.sleep 会在 java 中有所帮助。所以只是想知道你是否尝试过。
  • @muraliselenium 你完全正确!那解决了它。谢谢,祝您有美好的一天!
  • 好。祝你有美好的一天..

标签: python python-2.7 selenium selenium-webdriver


【解决方案1】:

根据 selenium 文档,设置 browser.implicity_wait(10) # seconds 告诉浏览器在确定元素不存在之前轮询页面 10 秒。默认情况下,它设置为 0 秒。设置后,该设置将在 webdriver 对象的生命周期内持续存在。

还有很多其他漂亮的工具可以等待元素加载,记录在 readthedocs.io

【讨论】:

    【解决方案2】:

    最有可能发生的情况是,当您从 bash 运行脚本时,脚本运行速度过快,并且在浏览器完成页面加载之前启动了 get_by_id 操作,从而导致此错误。

    正如@murali-selenium 建议的那样,您可能应该在开始在文档中查找内容之前添加一些等待时间。

    可以通过这种方式实现:

    #!/usr/bin/python
    from selenium import webdriver
    import time
    
    wait_time_sec = 1
    
    browser = webdriver.Firefox(firefox_binary='/usr/bin/firefox', executable_path="./geckodriver")
    
    # Get to the login page
    browser.get('https://example.com')
    time.sleep(wait_time_sec)
    browser.find_element_by_link_text('Application').click()
    time.sleep(wait_time_sec)
    
    # Login
    browser.find_element_by_id('username').send_keys('notmyusername')
    browser.find_element_by_id('password').send_keys('notmypassword')
    browser.find_element_by_css_selector('.btn').click()
    time.sleep(wait_time_sec)
    
    # Open the application
    try:
        browser.find_element_by_id('ctl00_Banner1_ModuleList_ctl01_lnkModule').click()
    except:
        print('failed')
    
    #browser.stop()
    

    【讨论】:

    • 根据 selenium 文档,这可能是一个更好的解决方案,具体取决于browser.implicitly_wait(10) # seconds 的情况。这使它在出错之前继续检查长达 10 秒。不过,我还没有测试过。 Link to the documentation
    • 可以确认,总的来说,browser.implicitly_wait(10) # seconds 绝对是更好的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    • 2019-12-22
    • 2020-08-23
    • 2017-09-03
    • 2013-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多