我正在使用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:fakepaththe_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"(。这是一种安全措施,可以避免泄露有关目录结构的信息。您可以忽略这个伪路径,因为正确的路径实际上是发送到输入的
C:fakepath
路由是大多数浏览器实现的一种安全措施,用于保护网页对文件系统的不必要访问。
尝试在发送密钥输入中使用文件的完整路径:
input.send_keys('C:/.../Users/xxxxx/the_image.jpg')
如果这不起作用,我通常会在C:/fakepath
中创建一个真正的fakepath目录来存储我的输入文件,但如果您将它们包含在存储库中以在虚拟环境中进行测试,则不建议这样做。
send_keys
应在不点击enter
键盘按钮的情况下上传文件。当您敲击Enter
键盘时,用于文件类型输入的send_keys
方法会将文件路径视为empty
,并且会像您的情况一样失败。
因此,您可以去掉与按下Enter
键相关的步骤,在这种情况下,这会导致不必要的问题。