7

现场打脸:如何使用Selenium批量上传文件?

 3 years ago
source link: https://www.kingname.info/2020/09/09/upload-multiple-file-by-selenium/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

现场打脸:如何使用Selenium批量上传文件?

发表于

2020-09-09

| 分类于 Python

| 评论数: 0

我们知道,Selenium里面,当我们获得一个 element 对象的时候,如果它是一个输入框,那么我们可以使用.send_keys()方法,模拟键盘按键,发送特定的字符串到输入框中,例如:

input_box = driver.find_element_by_xpath('//input[@class="xxx"]')
input_box.send_keys('账号 xxx')

但如果要说.send_keys()可以上传文件,你可能会非常吃惊吧。今天有个读者在问我的时候,我也非常吃惊,觉得这怎么可能:

2020-09-09-11-01-03.png

结果我到 Selenium 的文档里面一看,发现send_keys()竟然真的可以上传文件: 8.5. How to upload files into file inputs ?

2020-09-09-11-02-31.png

2020-09-09-11-04-31.png

为了验证这个说法,我们使用 Flask 手写一个支持上传功能的简陋网站。网站代码如下:

2020-09-09-12-21-09.png

网站运行效果如下图所示:

2020-09-09-11-08-09.png

点击“选择文件”按钮,在弹出的对话框里面选中一个文件,然后点击“Upload”按钮,就会把文件上传到代码里面的uploads文件夹中,如下图所示:

2020-09-09-12-22-49.png

现在我们在 Selenium 里面进行测试:

from selenium.webdriver import Chrome

driver = Chrome('./chromedriver')
driver.get('http://127.0.0.1:5000')
file_input = driver.find_element_by_xpath('//input[@type="file"]')
file_input.send_keys('/Users/kingname/test_send_keys/target/x.txt')
submit = driver.find_element_by_xpath('//input[@type="submit"]')
submit.click()

经过测试,发现确实可以正常上传文件。如下图所示:

2020-09-09-12-25-27.png

这样一来,既然 .send_keys()能够正常工作,那么就可以反向推测出,浏览器上传文件的原理,选择文件的对话框实际上提供给浏览器的仅仅是一个文件路径。当我们点击了上传按钮以后,浏览器会根据这个路径去读硬盘,找到这个文件然后上传。由于文件路径本质上就是一个字符串,所以用.send_keys()本质上就是直接替代了选择文件对话框生成的文件路径,直接把这个路径上传给了文件输入表单。

那么如何一次性上传多个文件呢?

只要网站支持同时上传多个文件,那么我们可以把多个文件的路径拼接到一个长字符串中,路径与路径之间使用换行符\n来进行分割。

假设在文件夹/Users/kingname/test_send_keys/target里面有多个文件,如下图所示:

2020-09-09-12-26-14.png

我们需要一次性全部上传。那么,可以使用换行符把每一个文件的路径拼接起来:

代码可以写为:

import os
from selenium.webdriver import Chrome
folder = '/Users/kingname/test_send_keys/target'
file_name_list = os.listdir(folder)
path_list = [os.path.join(folder, x) for x in file_name_list]
path_split_by_newline = '\n'.join(path_list)

driver = Chrome('./chromedriver')
driver.get('http://127.0.0.1:5000')
file_input = driver.find_element_by_xpath('//input[@type="file"]')
file_input.send_keys(path_split_by_newline)
submit = driver.find_element_by_xpath('//input[@type="submit"]')
submit.click()

运行效果如下图所示:

2020-09-09-12-30-18.png

成功上传多个文件。

谢乾坤 | Kingname wechat
第一时间获取最新文章更新,请订阅我的微信公众号:未闻Code

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK