selenium从本地上传文件到网页
Posted 蚂蚁小兵
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了selenium从本地上传文件到网页相关的知识,希望对你有一定的参考价值。
背景:
如下图,在用selenium 自动写博客的时候,需要上传本地图片到网页,问题产生了,selenium 可以控制网页,但是无法控制文件资源浏览器,怎么实现呢?
主要依赖库
- pyperclip:复制文本到剪切板
- pyautogui:鼠标键盘操控
- win32con/win32gui : window底层库
import pyautogui
import pyperclip
import win32con
import win32gui
上传单个文件
def main(self):
'''
前面不相关代码就屏蔽掉了
'''
#CSDN 文章编辑界面的上传图片按钮处理
add_photo = self.driver.find_element(By.XPATH, ".//div//button[@data-title='图片 – Ctrl+Shift+G']")
add_photo.click()
time.sleep(1)
choose_photo = self.driver.find_element(By.XPATH, ".//div[@class='uploadPicture']/input")
# 因为按钮不是button空间,所以不能直接用click(),要借助ActionChains
action = ActionChains(self.driver)
action.move_to_element(choose_photo).click().perform()
action.release()
time.sleep(1) # 等待一秒
file = r"D:\\Document\\scrapy\\image_all\\out_image_used\\长信怨\\3-1404231F932_长信怨_赏析_6.JPEG"
self.upload_file(file)
def upload_file(self, file_path):
try:
pyperclip.copy(file_path) # 把指定的路径拷贝到焦点
pyautogui.hotkey('ctrl', 'v')
time.sleep(1) # 等待一秒
pyautogui.press('enter') #进入到目标文件夹
except:
print(traceback.print_exc())
上传任意个指定文件(有限制,文件名总字节无法大于260)
- 比如 ,如果我想上传 文件夹下的所有文件
self.upload_files(file_dir,os.listdir(file_dir))
,那么如果这个文件夹下的所有文件名称的总字节超过260,那么就无不行了 - 我这里做了个简单处理,就是只上传第一个文件,因为selenium 正处于打开文件界面,我希望selenium关闭文件选择对话框,正常走下去
- 文件名最长可达多少个字符?
def main(self):
'''
前面不相关代码就屏蔽掉了
'''
#CSDN 文章编辑界面的上传图片按钮处理
add_photo = self.driver.find_element(By.XPATH, ".//div//button[@data-title='图片 – Ctrl+Shift+G']")
add_photo.click()
time.sleep(1)
choose_photo = self.driver.find_element(By.XPATH, ".//div[@class='uploadPicture']/input")
# 因为按钮不是button空间,所以不能直接用click(),要借助ActionChains
action = ActionChains(self.driver)
action.move_to_element(choose_photo).click().perform()
action.release()
time.sleep(1) # 等待一秒
file_dir = r"D:\\Document\\scrapy\\image_all\\out_image_used\\长信怨" #这是文件夹
self.upload_files(file_dir,["3-1404231F932_长信怨_赏析_6.JPEG","3-14041Q62234_长信怨_赏析_4.JPEG"])
# self.upload_files(file_dir,os.listdir(file_dir))
def upload_files(self, file_dir, file_list):
'''
:param file_dir: 待上传的文件夹路径
:param file_list: 待上传的文件列表(在 file_dir路径下)
有个硬伤:输入的文件列表转换字符串之后总字节无法超过260
:return:
'''
file_upload = ' '.join('"0"'.format(x) for x in file_list)
if len(file_upload) >= 260:
print("输入文件列表总字节大于260,无法上传!".format(len(file_upload)))
file_upload = os.path.join(file_dir, file_list[0])
try:
pyperclip.copy(file_dir) # 把指定的路径拷贝到焦点
pyautogui.hotkey('ctrl', 'v')
time.sleep(1) # 等待一秒
pyautogui.press('enter') # 进入到目标文件夹
'''将文件列表转为字符串 ,上传文件'''
pyperclip.copy(file_upload) # 把指定的路径拷贝到焦点
pyautogui.hotkey('ctrl', 'v')
time.sleep(1) # 等待一秒
pyautogui.press('enter') #进入到目标文件夹
except:
print(traceback.print_exc())
上传全部文件(需要win32gui库)
- 上传指定文件夹下的所有文件
- 这里用到了win32gui这个库,目的是根据文件对话框的名称找到这个对话框,并且获取到这个对话框的位置,然后pyautogui库模拟鼠标移动到对话框的文件中,再模拟Ctrl+A全选,
- 但是这里又有个弊端,无法过滤不想传的文件,真是头疼
def main(self):
'''
前面不相关代码就屏蔽掉了
'''
#CSDN 文章编辑界面的上传图片按钮处理
add_photo = self.driver.find_element(By.XPATH, ".//div//button[@data-title='图片 – Ctrl+Shift+G']")
add_photo.click()
time.sleep(1)
choose_photo = self.driver.find_element(By.XPATH, ".//div[@class='uploadPicture']/input")
# 因为按钮不是button空间,所以不能直接用click(),要借助ActionChains
action = ActionChains(self.driver)
action.move_to_element(choose_photo).click().perform()
action.release()
time.sleep(1) # 等待一秒
file_dir = r"D:\\Document\\scrapy\\image_all\\out_image_used\\长信怨" #这是文件夹
self.upload_file_all(file_dir)
def upload_file_all(self, dir):
try:
pyperclip.copy(dir) # 把指定的路径拷贝到焦点
pyautogui.hotkey('ctrl', 'v')
time.sleep(1) # 等待一秒
pyautogui.press('enter') # 进入到目标文件夹
'''根据文件资源管理器的名字定位'''
handle = win32gui.FindWindow("#32770", "打开")
'''文件资源管理器的位置'''
left, top, right, bottom = win32gui.GetWindowRect(handle)
'''将鼠标移动到文件资源管理器内部'''
pyautogui.moveTo(left+(right-left)/2, top+(bottom-top)/2, duration=0.25)
pyautogui.click()
pyautogui.hotkey('ctrl', 'a')#全选
button = win32gui.FindWindowEx(handle, 0, 'Button', "打开(&O)")
win32gui.SendMessage(handle, win32con.WM_COMMAND, 1, button) # 点击打开按钮
except:
print(traceback.print_exc())
参考资料:
win32gui
Python win32gui 模块,FindWindowEx() 实例源码
详解Python中pyautogui库的最全使用方法
以上是关于selenium从本地上传文件到网页的主要内容,如果未能解决你的问题,请参考以下文章
如何通过使用 Selenium Grid 将文件从本地计算机传输到远程 Web 服务器来上传文件
Selenium 网格执行 - 如何使用 sendkeys 将多个文件一起(一次)上传到网页
使用 Python 和 Selenium 将 APK 上传到解释为 URL 的网页