【问题标题】:Script can't find Element but Console can [Selenium] [Python]脚本找不到元素,但控制台可以 [Selenium] [Python]
【发布时间】:2019-07-19 12:59:13
【问题描述】:

我正在尝试编写脚本来自动化下载 Instagram 故事的过程,但尝试登录时我已经失败了。

我正在Pycharm 中编写代码。我只是尝试了解决任何问题的常用方法。首先,通过在控制台中输入命令来解决它,如果它可以在脚本中编写在控制台中工作的命令。但这是问题所在。在 python 控制台 中运行良好的函数在脚本中失败。

我注意到我的selenium 已过时,但升级它并没有帮助以太。我还做了一个新项目来测试天气有什么不同,但它没有。

我还尝试跳过脚本中的第一步,只打开我被重定向到的 url。但是第二个命令也失败了。

当我创建一个新变量来存储driver.find_element_by_link_text() 的输出时,它返回一个空列表。这让我相信 selenium 无法搜索页面的内容。

我也在 Chrome 和 Safari 上尝试过相同的方法。这也没有用。

代码如下:

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

driver = webdriver.Firefox()
driver.get("https://instagram.com/")
#next command fails
driver.find_element_by_link_text("Melde dich an.").click()

#if the first command is skipped by entering in the url 
#in driver.get(https://www.instagram.com/accounts/login/?source=auth_switcher)
#the following command fails as well.
driver.find_element_by_name("username").send_keys("HereIsTheUsername")
driver.find_element_by_name("password").send_keys("HereIsThePassword")
driver.find_element_by_name("password").send_keys(Keys.RETURN)
driver.close()

在控制台中,这些命令如前所述, 这是我在控制台中输入的内容:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("https://instagram.com/")
driver.find_element_by_link_text("Melde dich an.").click()
#if it failed here would be an error message
element = driver.find_element_by_name("username")

使用脚本,错误消息是这样的:

Traceback(最近一次调用最后一次):文件 "/Users/alisot2000/PycharmProjects/Instagram 下载器/venv/Main.py", 第 6 行,在 driver.find_element_by_link_text("Melde dich an.").click() 文件 "/Users/alisot2000/PycharmProjects/Instagram 下载器/venv/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", 第 428 行,在 find_element_by_link_text 中 返回 self.find_element(by=By.LINK_TEXT, value=link_text) 文件“/Users/alisot2000/PycharmProjects/Instagram 下载器/venv/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", 第 978 行,在 find_element 中 'value': value})['value'] 文件“/Users/alisot2000/PycharmProjects/Instagram 下载器/venv/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", 第 321 行,在执行中 self.error_handler.check_response(response) 文件“/Users/aliot2000/PycharmProjects/Instagram 下载器/venv/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", 第 242 行,在 check_response 中 引发异常类(消息,屏幕,堆栈跟踪) selenium.common.exceptions.NoSuchElementException:消息:无法 定位元素:Melde dich an。

【问题讨论】:

  • 您如何确定控制台找到了该元素?你用它来验证了吗?
  • 从上一条错误消息中可以清楚地看出脚本没有找到该元素。它通常发生在不能直接使用selenium 的网站。
  • 对我来说似乎是一个同步问题。在尝试查找用户名元素之前添加显式等待。

标签: python selenium


【解决方案1】:

您可能遇到的问题:

1。同步问题

对于大多数自动化任务,网页的加载时间会根据机器的处理能力和您的互联网连接强度而有所不同。

为了解决这个问题,我们可以使用来自 selenium 的库导入等待。 下面是一个示例:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "myDynamicElement"))
    )
finally:
    driver.quit()

2。 selenium 配置文件中设置了错误的语言

Selenium 在大多数情况下会在运行自动化脚本时使用您的语言环境,但如果您可能需要其他语言,这里是 FireFox 的示例代码。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary

profile = webdriver.FirefoxProfile()
# switch out 'de' with another two character language code
profile.set_preference("intl.accept_languages",'de')
driver = webdriver.Firefox(firefox_profile=profile, executable_path='<insert_your_gecko_driver_path_here>')

driver.get("https://instagram.com/")
driver.close()

3。工作代码(在 Mojave 10.14.5 上测试)

这是您的代码和更改后的代码的差异:https://www.diffchecker.com/G0WWB4Ry

  1. 设置虚拟环境
  2. pip 安装硒
  3. 下载壁虎驱动
  4. 在代码中设置壁虎驱动程序的路径
  5. 运行脚本并获得成功结果
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# these two imports are for setting up firefox driver and options 
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
# import these three lines below if you are having synchronization issues
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

profile = webdriver.FirefoxProfile()
# here is where you need to set your language explicitly if its defaulting to an undesired language
# just replace the second parameter with your 2 character language code
# this line is not needed if your desired language is locale
profile.set_preference("intl.accept_languages",'de')
# throw in your path here <insert_your_gecko_driver_path_here>
driver = webdriver.Firefox(firefox_profile=profile, executable_path='<insert_your_gecko_driver_path_here>')

driver.get("https://instagram.com/")

# added these two lines below to solve synchronization issue 
# element wasnt clickable until page finished loading
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "Melde dich an.")))
#next command fails 
driver.find_element_by_link_text("Melde dich an.").click()

#if the first command is skipped by entering in the url 
#in driver.get(https://www.instagram.com/accounts/login/?source=auth_switcher)
#the following command fails as well.
driver.find_element_by_name("username").send_keys("HereIsTheUsername")
driver.find_element_by_name("password").send_keys("HereIsThePassword")
driver.find_element_by_name("password").send_keys(Keys.RETURN)
driver.close()

【讨论】:

  • 非常感谢您的详细回复。同步确实是问题所在。等待一秒钟即可解决问题。
【解决方案2】:
def ClickElementByName(name,driver): 
    while True:
        try:
            driver.find_element_by_name(name).click()
            break
        except:
            sleep(1)
            pass
 Too long to wait the website run.
 Replace ClickElementByName("username", driver)

【讨论】:

    【解决方案3】:

    driver.find_element_by_xpath('//input[@name="username"]').send_keys("HereIsTheUsername") driver.find_element_by_xpath('//input[@name="password"]').send_keys("HereIsTheUsername") driver.find_element_by_xpath('//div[text()="登录"]').click()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      • 2015-12-30
      • 1970-01-01
      • 2021-12-17
      • 2018-11-07
      • 2019-06-20
      • 1970-01-01
      相关资源
      最近更新 更多