【问题标题】:Python Selenium: send_keys not sending the actual path to a file input elementPython Selenium:send_keys 未将实际路径发送到文件输入元素
【发布时间】:2020-07-11 13:03:26
【问题描述】:

我正在使用 Python Selenium 和 ChromeDriver 为网页提供输入以上传文件。根据我读过的所有文档和 StackOverflow 答案,通过 send_keys 将完整文件路径发送到输入元素应该会自动执行此操作(我什至对简单的文本输入也有类似的工作)。但它不起作用。

我已将其隔离为一个最小的示例:

HTML:

<input type="file" class="the_input">

Python:

import time

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys

options = Options()
options.add_argument('--user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1"')
options.add_argument('--window-size=375,812')
options.add_argument('user-data-dir=selenium')
browser = webdriver.Chrome(options=options)

browser.get('file:///xxxxx.html')
time.sleep(2)

input = browser.find_elements_by_class_name('the_input')[0]
print('attempting to change input')
input.clear()
print('input value:', input.get_attribute('value'))
input.send_keys('/Users/xxxxx/the_image.jpg')
print('input value:', input.get_attribute('value'))
input.send_keys(Keys.ENTER)

print('quitting')
browser.quit()

当 /Users/xxxxx/the_image.jpg 路径无效时,运行它会抛出第一行 'send_keys' 行(发送路径字符串):

attempting to change input
input value: 
Traceback (most recent call last):
...
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: File not found : /Users/xxxxx/the_image.jpg

这似乎是合理的。

但是,当 /Users/xxxxx/the_image.jpg 路径为 有效 时,运行相同的操作将在第二个 'send_keys' 行(发送 ENTER)处抛出:

attempting to change input
input value: 
input value: C:\fakepath\the_file.png
Traceback (most recent call last):
...
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: File not found : 

这让我大吃一惊:似乎我的有效路径被替换为虚假路径 C:\fakepath\the_file.png(我什至不在 Windows 上)。我猜这是 Selenium 和 ChromeDriver 之间的安全相关行为。但如果这是预期的行为,我错过了什么,其他人是如何做到这一点的?甚至可以像这样完全自动化上传流程吗?


更新/回答

这里有两个不同的问题:

  • 发送 ENTER 键是错误的。只需发送文件路径即可按预期运行。相当于用户打开文件选择对话框,选择一个文件,然后点击打开。如果您在此之后还发送 ENTER,则相当于将输入的值重置为空(这解释了我看到的“找不到文件:”错误)。
  • 如果您在发送文件路径后查询输入的值,您将看到您的实际文件名,但路径是虚假的(“C:\fakepath\correct_file_name.png”)。这是一种安全措施,可避免泄露有关您的目录结构的信息。您可以忽略此虚假路径,因为正确的路径实际上已发送到输入。

【问题讨论】:

  • 您为什么在file 输入字段上单击Enter。 send_keys 应该在不点击enter 键盘按钮的情况下上传文件。当您点击Enter 键盘时,send_keys 用于file 类型输入的方法会将文件路径视为空,并且会像您的情况一样失败。
  • 这是一种来自浏览器(在本例中为 Chrome)的安全措施,用于隐藏文件的实际路径(因为它会将文件结构暴露给服务器)。尝试使用文件的完整路径,例如:C:/Users/xxxxx/the_image.jpg
  • 网页是否通过JavaScript处理文件上传?如果是,那么您必须首先修改输入元素并使其可供 Selenium 访问
  • @supputuri 你说得对,我不需要发送 ENTER 键,结果是输入的更改侦听器在第一个 send_keys 之后立即触发。
  • @LucasSousa 感谢您的解释,这是有道理的,但是哇,伪造的文件完全让我感到困惑。

标签: python selenium selenium-chromedriver browser-automation


【解决方案1】:

C:\fakepath\ 路由是大多数浏览器实施的一种安全措施,用于防止网页对您的文件系统进行不必要的访问。

尝试在发送键输入中使用文件的完整路径:

input.send_keys('C:/.../Users/xxxxx/the_image.jpg')

如果这不起作用,我通常会在 C:/fakepath 中创建一个真正的 fakepath 目录来存储我的输入文件,但如果您将它们包含在存储库中以便在虚拟环境中进行测试,则不建议这样做。

【讨论】:

  • 要清楚,“/Users/xxxxx/the_image.jpg”是正确的完整路径(我在 Mac 上,我只是将我的用户名替换为 xxxxx 以便在此处发布)。让我大吃一惊的是,即使我向输入发送了正​​确的路径,调用 input.get_attribute('value') 也会返回“C:\fakepath\the_file.png”。这是安全/隐私措施。但即便如此,事情还是按预期工作(真正的路径实际上是通过)。
【解决方案2】:

send_keys 应该在不点击enter 键盘按钮的情况下上传文件。当您点击Enter 键盘时,文件类型输入的send_keys 方法会将文件路径视为empty,它会像您的情况一样失败。

因此,您可以取消与点击Enter 键相关的步骤,这在这种情况下会导致不必要的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-03
    • 2013-07-12
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2019-10-20
    相关资源
    最近更新 更多