vlambda博客
学习文章列表

利用向日葵, Webdriver, Autoit 实现远程办公自动化之 向网页中多个位置上传不同图片


由于工作原因,我需要向网站中的页面上传不同的照片,由于设备网络缓慢,操作繁琐,不得不请专人来完成这个工作,有时恨不得砸掉设备。

今年由于外贸订单锐减,我也闲暇下来,等待公司的进一步动作,减薪裁员在所难免。既然闲下来,就要做点有用的事情,要是能够让上传图片自动化就好了。之前我也放出'豪言',要用代码解决这个山芋。于是说干就干。

零. 解决手机文件上传到远程电脑文件夹的问题

首先我需要用一个更方便的手机拍照,然后上传到远程运行代码的电脑上面,电脑上网速度不是问题,那么怎样才能让手机照片立马传到电脑指定文件夹呢?我首先到想网盘,但是网盘需要从手机上传图片到APP, 然后再从电脑上的网盘APP下载到电脑,慢慢慢,繁琐。后来想到我常用的向日葵,它有一个远程文件的功能,能够实时从手机上传图片到电脑的文件夹,快,又简便。后来也尝试用teamviewer,感觉太臃肿了,不好操作放弃。于是就定下来用向日葵来上传文件。


一. webdriver

webdriver是所有代码的驱动,用它去完成所有自动化的点击输入等操作。

 pip3 install selenium

下载chromedriver

把下载下来的chromedriver.exe剪切到python安装目录的Scripts文件夹下,我放在 D:\Program Files\Python\Python37\Scripts目录下

然后测试一下

页面

在Username里面 鼠标右键 , 检查

就会看到对应的网页代码第2步,再鼠标右键CopyCopy XPath

利用向日葵, Webdriver, Autoit 实现远程办公自动化之 向网页中多个位置上传不同图片

然后作为到 browser.find_element_by_xpath的参数字符串

 from selenium import webdriver
 browser = webdriver.Chrome()
 browser.get('http://www.mypage.com') #打开网页
 path = browser.find_element_by_xpath('/html/body/div/b/div/form/div[1]/input') #定位需要输入用户名的地方,并复制在引号里。如果复制内容里面有引号,需改为单引号,整个字符串用双引号
 path.send_keys('myid') #测试成功


同样的道理,Password 处输入 mypwd

 path = browser.find_element_by_xpath('/html/body/div/b/div/form/div[2]/input')
 path.send_keys('mypwd')

同理,我们可以操作浏览器上的所有步骤,注意有些地方需要等待些时间让,网页显示出来才进行下一步操作。知道直到上传图片按钮时,会跳出windows窗口,这时webdriver就操作不了了。就要借助其他比如:Autoit的帮忙


二. Autoit

A.下载

B.识别上传图片的窗口

打开Autoit window info,拖动风扇标志到需要输入文件名的窗口,记录识别出来的窗口信息,如下。再拖动风扇到打开按钮处,同样识别出它的信息,并记录。

利用向日葵, Webdriver, Autoit 实现远程办公自动化之 向网页中多个位置上传不同图片

C. 记录参数

title:打开

title_class: #32770

文件名输入框的ClassnameNN(类型+Instance): Edit1(类型+Instance)

打开按钮的ClassnameNN(类型+Instance):Button1

D.编辑代码

打开SciTE Script Editor 编辑代码,例如

 ControlFocus("打开", "", "Edit1");
 WinWait("[CLASS:#327701]", "", 10);
 ControlSetText("打开", "", "Edit1", "D:\autoupload\uploadpic\434976.jpeg");
 Sleep(2000);
 ControlClick("打开", "", "Button1");

现在我们先只单独上传一个照片,作为测试。

E.中文显示??问题

如果代码中中文出现?显示,说明你的编码有问题。

FileEncoding, 选择 UTF-8

F.试运行代码

先保存 代码au3文件,然后ToolsGo, 或者直接按 F5

没有报错说明运行正常

G.转换成EXE

打开Compile Script to .exe, 如图把AU3转换成EXE

利用向日葵, Webdriver, Autoit 实现远程办公自动化之 向网页中多个位置上传不同图片

三.webdriver调用上一步生成的EXE文件

 plus = browser.find_element_by_xpath("//*[@id='imgToolBar']/button[1]/i")
 plus.click() #打开添加图片按钮
 os.system(r'D:\autoupload\Autoitfile\test.exe') #调用Autoit实现自动上传
 time.sleep(5)
 savepic = browser.find_element_by_xpath("//*[@id='imgToolBar']/button[2]/i")
 savepic.click() #点击保存图片按钮
 time.sleep(10)#等待5秒
 okbutton = browser.find_element_by_xpath('/html/body/div[4]/div[2]/div/div/div/div/div[4]/button')
 okbutton.click() #保存成功后点击OK

四.实现多图片上传

 ControlSetText("打开", "", "Edit1", "D:\autoupload\uploadpic\434976.jpeg");

Autoit 使用参数 $CmdLine[1] , 里面的1表示第一个参数,详细使用方法见 其他相关 C

替换为

 ControlSetText("打开", "", "Edit1", $CmdLine[1]);

然后我们就对这个参数进行在调用exe文件的时候进行赋值如下:

 os.system(r'D:\autoupload\autoitfile\uploadpic.exe %s' %eachpicpath)

上面 %s 就代表 $CmdLine[1]的值,把后面 eachpicpath 这个变量的值赋给$CmdLine[1]

我们只要通过循环把多张照片的路径赋值给eachpicpath就可以了,这样实现了多张照片的上传。


五.用webdriver模拟鼠标操作解决图片轮播的问题

当我在用连续上传图片的时候发现网页使用了Bootstrap的轮播效果,导致定位失败,无法继续上传。

每当上传第二张照片的时候,网页就开始循环播放图片,图片和相关的按钮也变换对应的值,所以原来设定的定位位置就发生了变化。通过查询大量的资料和不断的研究网页的文件发现,是网页是在调用Bootstrap.min.js文件,来控制轮播,其中这段代码正是控制轮播的速度和方法

     c.DEFAULTS = {
         interval: 5e3,
         pause: "hover",
         wrap: !0,
         keyboard: !0
    },

详细资料参考其他相关 D

选项名称 类型/默认值 Data 属性名称 描述
interval number 默认值:5000 data-interval 自动循环每个项目之间延迟的时间量。如果为 false,轮播将不会自动循环。
pause string 默认值:"hover" data-pause 鼠标进入时暂停轮播循环,鼠标离开时恢复轮播循环。
wrap boolean 默认值:true data-wrap 轮播是否连续循环。

但是我试着修改 interval的值来阻止轮播,失败。又停止加载JS文件,网页根本无法运行,方法失败。同时我发现,如果我手动进入网页,网页并没有轮播,上面表格也看到 鼠标进入时暂停轮播循环,鼠标离开时恢复轮播循环。于是我试着当图片正在轮播时,把鼠标移动到图片上,但是图片还是在轮播。那既然手动进入系统网页的时候,可以防止轮播,那就模拟鼠标操作进行点击。webdriver是有相关的功能,果不其然,模拟鼠标点击放弃自动点击可以有效的防止轮播,问题解决。

我们需要这样调用

 from selenium.webdriver.common.action_chains import ActionChains
 browser = webdriver.Chrome() #实例化浏览器
 submit = browser.find_element_by_xpath('/html/body/div/b/div/form/div[3]/div/button') #定位位置
 ActionChains(browser).move_to_element(submit).click().perform() #鼠标点击,执行

其他关于webdriver鼠标调用详细资料,参考 其他相关 E


六. 不能通过 os.path.getsize(path)判断文件是否为空

明明文件夹已经删除所有的文件,但是返回值的值不为0, 原因是它的值表示描述该目录的文件的大小,其中包含有关文件和目录的信息,一旦里面存在过文件,都可能导致值不为0. 可以通过,len(os.path.listdir(dirname))来判断是否有文件存在。

七.通过 os.path.listdir(dirname)出现文件名多了'.###'

当文件夹中的文件全部删除后,然后通过向日葵往该文件夹上传图片时,由于上传的时间与该命令执行的时间差,当命令执行时,文件还没有生成完整,导致命令得到的文件名后面多了‘.###’而出现错误。所以需要在文件名上进行判断,如果文件名不正确,我们

 if not '.###' in eachpica:
     print(eachpica)

八.xpath定位出现变化的值

在定位一个关闭按钮时,发现按钮的属性值是一个变化的值,如下:box后面的值

 "//*[@id='jconfirm-box94508']/div/div/div[1]/div/button/i"

每次打开这个页面都会出现不同的属性值,而且也没有找到这个值的算法。不过通过chrome我发现,它的full xpath找的属性是唯一的,这样就解决了问题。

 "/html/body/div[3]/div[2]/div/div/div/div/div[3]/div/div/div/div[1]/div/button/i"

九.向不同的问题点上传多张图片

在大图区实现上传多张图片之后,还要到随后的问题点的位置上传多张图片。所以我又新建了几个常用问题点的文件夹,如图:

利用向日葵, Webdriver, Autoit 实现远程办公自动化之 向网页中多个位置上传不同图片

让程序在这里循环,当我通过向日葵向对应文件夹上传图片后,程序就可以扫描到文件夹不为空,就通过os.listdir()得到所有上传图片的文件名,然后进行对应的上传,完成后删除对应图片。在文件内部循环上传完图片后再退出到uploadpic文件夹内扫描各个文件夹,等待不为空的文件夹。

     while True:
         print('扫描所有文件夹。')
         rootlist = os.listdir(rootpath)
         print(rootlist)
         pathlista = os.listdir(afilepath)
         print(pathlista)
         pathlistc = os.listdir(cfilepath)
         print(pathlistc)
         pathlists = os.listdir(sfilepath)
         print(pathlists)
         pathlistz = os.listdir(zfilepath)
         print(pathlistz)
 
         
         asize = len(pathlista)
         print('asize', asize)
         csize = len(pathlistc)
         print('csize', csize)
         ssize = len(pathlists)
         print('ssize', ssize)
         zsize = len(pathlistz)
         print('zsize', zsize)
 
         
         if asize != 0:
             print(asize)
             print('在A文件夹里上传。')
             try:
                 uploadpic(acamelement, pathlista, afilepath) #在A文件夹里上传图片
             except:
                 continue
 
         if csize != 0:
             print(csize)
             print('在C文件夹里上传。')
             try:
                 uploadpic(ccamelement, pathlistc, cfilepath)#在C文件夹里上传图片
             except:
                 continue
 
         if ssize != 0:
             print(ssize)
             print('在S文件夹里上传。')
             try:
                 uploadpic(scamelement, pathlists, sfilepath) #在S文件夹里上传图片
             except:
                 continue
             
         if zsize != 0:
             print(zsize)
             print('在Z文件夹里上传。')
             try:
                 uploadpic(zcamelement, pathlistz, zfilepath) #在Z文件夹里上传图片
             except:
 


十.退出当前订单号

目前uploadpic是在同一个订单号内,当我们上传完了所有图片后,就需要退出当前订单。退回到输入PO号的位置。所以我传入一个end.jpg图片,接前面当程序在uploadpic识别到这个图片时,就关掉当前PO号。

         if 'end.jpg' in rootlist:
            closepo = browser.find_element_by_xpath("//*[@id='po_info_box']/div[1]/div/button[3]/i")
            ActionChains(browser).move_to_element(closepo).click().perform()
            os.remove(r'D:\autoupload\uploadpic\end.jpg')
            showhide = browser.find_element_by_xpath("//*[@id='row_inspect_general']/div[1]/div[3]/button[1]")
            ActionChains(browser).move_to_element(showhide).click().perform()
            print('将要退出这个订单。')
            break

十一.怎样通过向日葵输入订单号

向日葵有CMD功能,及可以通过手机向电脑输入命令

利用向日葵, Webdriver, Autoit 实现远程办公自动化之 向网页中多个位置上传不同图片

但是,此功能只局限于电脑系统的内部命令,比如ipconfig之类。想用CMD命令来运行python程序,此功能就没有作用了。如何向程序传达订单号的命令呢?通过input订单号需要在cmd界面或者IDLE输入订单号,这样就需要退出远程文件,再进入桌面控制,这样就显得繁琐了。所以我想到在uploadpic的文件夹内新建一个叫订单号文件夹,然后再在里面新建一个文件夹,文件夹的名称及输入需要打开的订单号,当变量得到这个订单号后立即删除这个空的文件夹,但仍然保留订单号的文件夹。在远程文件夹里新建一个文件夹时非常方便的。

 while True:
     popathlist = os.listdir(popath) #检测订单号文件夹里的文件
     posize = len(popathlist)
     print('请传入PO号的文件夹。')
     waitok("//*[@id='nr_cont']")
     pono = browser.find_element_by_xpath("//*[@id='nr_cont']")
     pono.clear() #需要清空订单号栏的文字
     if posize != 0: #当有订单号文件夹出现
         print('识别到PO号。')
         pofilename = popathlist[0] #当有订单号为名的文件夹出现后,把订单号赋值给变量
         os.rmdir(''.join([popath, '\\', pofilename]))#删除文件夹
     else:
         print('未扫描到PO号的文件夹.')
         continue
         
     pono.send_keys(pofilename) #输入订单号
     filter = browser.find_element_by_xpath("//*[@id='row_inspect_general']/div[1]/div[3]/button[2]")
     ActionChains(browser).move_to_element(filter).click().perform()    
 
     try:#后面try, except语句用于判断po号是否正确。
         WebDriverWait(browser, 5, 0.5).until(EC.presence_of_element_located((By.XPATH, "//*[@id='reportTable']/tbody/tr/td[2]/button")))
         print('将要打开PO')
         openbutton = browser.find_element_by_xpath("//*[@id='reportTable']/tbody/tr/td[2]/button")
         ActionChains(browser).move_to_element(openbutton).click().perform()
 
 
     except:
         try:
             WebDriverWait(browser, 3, 0.5).until(EC.presence_of_element_located((By.XPATH, "//*[@id='reportTable']/tbody/tr/td")))
             print('PO号不存在.请重新输入。')
             showhide = browser.find_element_by_xpath("//*[@id='row_inspect_general']/div[1]/div[3]/button[1]")
             ActionChains(browser).move_to_element(showhide).click().perform()        
             continue
         except:
             print('出现未知错误,系统退出。')
             browser.quit()
             sys.exit()

十二. 等待

由于网络原因,有时候需要等待,有些页面上的元素才会出现,我们就需要在程序中做出相应的等待。等待主要有三种,详情参考其他相关 F

在本例中,我主要使用了显性等待和强制等待结合。首先等元素出现后,再短暂等待。

有时候,当页面已经出现某个元素后,也需要等待短暂时间让其他相关准备好。这样才可以避免出错。

下面是显性等待的函数

 def waitok(location):
     locator = (By.XPATH, location)
     try:
         WebDriverWait(browser, 30, 0.5).until(EC.presence_of_element_located(locator))
     except:
         print('网络问题,页面加载失败。')
         browser.quit()
         sys.exit()
 


十三.其他相关

A. webdriver 的Keys()类提供键盘上所有按键的操作

from selenium.webdriver.common.keys import Keys在使用键盘按键方法前需要先导入keys 类包。下面经常使用到的键盘操作:send_keys(Keys.BACK_SPACE) 删除键(BackSpace)send_keys(Keys.SPACE) 空格键(Space)send_keys(Keys.TAB) 制表键(Tab)send_keys(Keys.ESCAPE) 回退键(Esc)send_keys(Keys.ENTER) 回车键(Enter)send_keys(Keys.CONTROL,'a') 全选(Ctrl+A)send_keys(Keys.CONTROL,'c') 复制(Ctrl+C)

B. 关闭当前页面,关闭浏览器

参考 https://www.cnblogs.com/muchengnanfeng/p/9553186.html

C. $CmdLine 参数的使用

参考 https://blog.csdn.net/kittyboy0001/article/details/25557147

D. Bootstrap 轮播(Carousel)插件

https://www.runoob.com/bootstrap/bootstrap-carousel-plugin.html

E.python+selenium-UI自动化之鼠标操作

https://www.lizenghai.com/archives/20026.html

 单击鼠标左键 :click(on_element=None)
 单击鼠标右键:context_click(on_element=None)
 单击鼠标左键不松开:click_and_hold(on_element=None)
 双击鼠标左键:double_click(on_element=None)
 将鼠标从某个元素(source)按下去拖拽到某个元素(target)然后松开:        drag_and_drop(source, target)
 将鼠标从某个元素(source)拖拽到某个坐标然后松开:drag_and_drop_by_offset(source, xoffset, yoffset)
 鼠标从当前位置移动到某个坐标:move_by_offset(xoffset, yoffset)
 鼠标移动到某个元素:move_to_element(to_element)
 移动到距某个元素(左上角坐标)多少距离的位置:move_to_element_with_offset(to_element, xoffset, yoffset)
 在某个元素位置松开鼠标左键:release(on_element=None)
 执行链条中所有操作:perform()

F.关于三种等待以及BY定位

参考 https://huilansame.github.io/huilansame.github.io/archivers/sleep-implicitlywait-wait

https://www.cnblogs.com/bzdmz/p/10360311.html

ind_element(By.ID,"kw")find_element(By.NAME,"wd")find_element(By.CLASS_NAME,"s_ipt")find_element(By.TAG_NAME,"input")find_element(By.LINK_TEXT,u"新闻")find_element(By.PARTIAL_LINK_TEXT,u"新")find_element(By.XPATH,"//*[@class='bg s_btn']")find_element(By.CSS_SELECTOR,"span.bg s_btn_wr>input#su")

十四.详细源码:

 #encoding = UTF-8
 
 from selenium import webdriver
 from selenium.webdriver.common.action_chains import ActionChains
 from selenium.webdriver.support.wait import WebDriverWait
 from selenium.webdriver.support import expected_conditions as EC
 from selenium.webdriver.common.by import By
 import time
 import os
 import sys
 
 #定义显性等待,参数为需要等待出现的具体元素的xpath值
 def waitok(location):
     locator = (By.XPATH, location)
     try:
         WebDriverWait(browser, 30, 0.5).until(EC.presence_of_element_located(locator))
     except:
         print('网络问题,页面加载失败。')
         browser.quit()#如果出现长时间(30秒)不能加载完成,就关闭浏览器,退出程序。
         sys.exit()
 
     
 #定义多个图片上传的函数,参数分别为:对应问题点相机元素位置,电脑中对应问题点的文件夹中文件列表,
 #以及对应问题点的文件夹路径。
 def uploadpic(camelement, pathlist, picfilepath):
     waitok(camelement) #显性等待相机元素出现
     time.sleep(1)#再短暂等待,让其他元素准备好。
     frontcam = browser.find_element_by_xpath(camelement)
     ActionChains(browser).move_to_element(frontcam).click().perform()#为了避免图片轮播,模拟鼠标点击
     print('打开相机')
     for eachpic in pathlist:
         if not '.###' in eachpic:#由于上传图片需要时间,会在文件夹中出现临时文件。如果是临时文件,就暂不处理,等待主程序下次循环。
             print(eachpic)
             print('将要保存这个图片.')
             eachpicpath = ''.join([picfilepath, '\\', eachpic])#得到图片的绝对路径
             waitok("//*[@id='imgToolBar']/button[1]/i")#显性等待
             time.sleep(1)#强制等待
             plus = browser.find_element_by_xpath("//*[@id='imgToolBar']/button[1]/i")
             print('开始添加图片.')
             ActionChains(browser).move_to_element(plus).click().perform()
             os.system(r'D:\autoupload\autoitfile\uploadpic.exe %s' %eachpicpath) #autoit处理windows窗口
             waitok("//*[@id='imgToolBar']/button[2]/i")
             time.sleep(1)
             savepic = browser.find_element_by_xpath("//*[@id='imgToolBar']/button[2]/i")
             print('保存图片。')
             ActionChains(browser).move_to_element(savepic).click().perform()
             waitok('/html/body/div[4]/div[2]/div/div/div/div/div[4]/button')
             okbutton = browser.find_element_by_xpath('/html/body/div[4]/div[2]/div/div/div/div/div[4]/button')                            
             ActionChains(browser).move_to_element(okbutton).click().perform()
             os.remove(eachpicpath)#删除已经上传的图片
     waitok("/html/body/div[3]/div[2]/div/div/div/div/div[3]/div/div/div/div[1]/div/button/i")
     #上传完一组照片后,就会关闭上传窗口,等待主程序下次循环,再上传
     closebutton = browser.find_element_by_xpath("/html/body/div[3]/div[2]/div/div/div/div/div[3]/div/div/div/div[1]/div/button/i")
     ActionChains(browser).move_to_element(closebutton).click().perform()
 
 #各个位置的相机元素位置
 acamelement = "//*[@id='pict-98']/i"
 ccamelement = "//*[@id='pict8']/i"
 scamelement = "//*[@id='pict10']/i"
 zcamelement = "//*[@id='pict-99']/i"
 
 #各个位置在电脑中对应的文件夹位置
 afilepath = r'D:\autoupload\uploadpic\a大图'
 cfilepath = r'D:\autoupload\uploadpic\c清洁度'
 sfilepath = r'D:\autoupload\uploadpic\s针车'
 zfilepath = r'D:\autoupload\uploadpic\z其他'
 popath = r'D:\autoupload\uploadpic\订单号'
 rootpath = r'D:\autoupload\uploadpic'
 
 #主程序
 browser = webdriver.Chrome()#打开浏览器
 browser.maximize_window()#最大化浏览器窗口
 browser.get('网站地址') #打开网页
 waitok('/html/body/div/b/div/form/div[1]/input')
 myid = browser.find_element_by_xpath('/html/body/div/b/div/form/div[1]/input') #定位需要输入用户名的地方,并复制在引号里。如果复制内容里面有引号,需改为单引号,整个字符串用双引号
 myid.send_keys('登录名') #输入登录名
 mypwd = browser.find_element_by_xpath('/html/body/div/b/div/form/div[2]/input')
 mypwd.send_keys('密码') #输入密码
 submit = browser.find_element_by_xpath('/html/body/div/b/div/form/div[3]/div/button')#提交
 ActionChains(browser).move_to_element(submit).click().perform()
 waitok('/html/body/div/aside[1]/section/ul/div[2]/li[2]/a/span')
 inslist = browser.find_element_by_xpath('/html/body/div/aside[1]/section/ul/div[2]/li[2]/a/span')#进入inspection list
 ActionChains(browser).move_to_element(inslist).click().perform()
 waitok("/html/body/div[1]/div[1]/section[2]/div[6]/div[1]/div[2]/div[1]/div[5]/div/div/div/div/select/option[5]")
 selectall = browser.find_element_by_xpath("/html/body/div[1]/div[1]/section[2]/div[6]/div[1]/div[2]/div[1]/div[5]/div/div/div/div/select/option[5]")
 selectall.click() #点击ALL,由于这里用模拟鼠标操作会出现报错,就直接点击了。
 
         
         
 #主循环
 while True:
     popathlist = os.listdir(popath)#扫描订单号文件夹里面有没有订单号为名的文件夹
     posize = len(popathlist)
     print('请传入PO号的文件夹。')
     waitok("//*[@id='nr_cont']")
     pono = browser.find_element_by_xpath("//*[@id='nr_cont']")#定位输入订单号文本的位置
     pono.clear()#清空文本栏。如果输错需要返回这里,所以在输入前需要清空文本栏。
     if posize != 0:#有文件出现
         print('识别到PO号。')
         pofilename = popathlist[0]#导出输入的订单号,并赋值给变量
         os.rmdir(''.join([popath, '\\', pofilename]))#把订单号名的文件夹删除
     else:
         print('未扫描到PO号的文件夹.')#如果没有扫描到文件就返回重新循环。
         continue
         
     pono.send_keys(pofilename) #在文本栏输入订单号
     #点击查找对应的订单
     filter = browser.find_element_by_xpath("//*[@id='row_inspect_general']/div[1]/div[3]/button[2]")
     ActionChains(browser).move_to_element(filter).click().perform()    
 
     try:#对输入错误订单的情况进行处理
         WebDriverWait(browser, 5, 0.5).until(EC.presence_of_element_located((By.XPATH, "//*[@id='reportTable']/tbody/tr/td[2]/button")))
         print('将要打开订单')
         openbutton = browser.find_element_by_xpath("//*[@id='reportTable']/tbody/tr/td[2]/button")
         ActionChains(browser).move_to_element(openbutton).click().perform()
 
 
     except:#如果输入错误
         try:
             WebDriverWait(browser, 3, 0.5).until(EC.presence_of_element_located((By.XPATH, "//*[@id='reportTable']/tbody/tr/td")))
             print('PO号不存在.请重新输入。')
             #如果输入错误,打开隐藏,显示输入订单号的地方,再重新循环,重新输入订单号
             showhide = browser.find_element_by_xpath("//*[@id='row_inspect_general']/div[1]/div[3]/button[1]")
             ActionChains(browser).move_to_element(showhide).click().perform()        
             continue
         except:#如果还出错,就退出系统
             print('出现未知错误,系统退出。')
             browser.quit()
             sys.exit()
 
     #进入上传图片的内部循环
     while True:
         print('扫描所有文件夹。')
         rootlist = os.listdir(rootpath)
         print(rootlist)
         pathlista = os.listdir(afilepath)
         print(pathlista)
         pathlistc = os.listdir(cfilepath)
         print(pathlistc)
         pathlists = os.listdir(sfilepath)
         print(pathlists)
         pathlistz = os.listdir(zfilepath)
         print(pathlistz)
 
         
         asize = len(pathlista)
         print('asize', asize)
         csize = len(pathlistc)
         print('csize', csize)
         ssize = len(pathlists)
         print('ssize', ssize)
         zsize = len(pathlistz)
         print('zsize', zsize)
 
         #如果对应的文件夹里有准备上传的图片,就会进行上传,
         #不包括还处于临时文件名的图片,暂时会略过,等文件从手机上传完毕后,恢复正常文件名,再进行上传。
         if asize != 0:
             print(asize)
             print('在A文件夹里上传。')
             try:
                 uploadpic(acamelement, pathlista, afilepath)
             except:
                 continue
 
         if csize != 0:
             print(csize)
             print('在C文件夹里上传。')
             try:
                 uploadpic(ccamelement, pathlistc, cfilepath)
             except:
                 continue
 
         if ssize != 0:
             print(ssize)
             print('在S文件夹里上传。')
             try:
                 uploadpic(scamelement, pathlists, sfilepath)
             except:
                 continue
             
         if zsize != 0:
             print(zsize)
             print('在Z文件夹里上传。')
             try:
                 uploadpic(zcamelement, pathlistz, zfilepath)
             except:
                 continue
 
         #上传完所有图片后,从手机上传end.jpg到uploadpic文件夹,程序识别到这个图片后就会关闭该订单
         #打开隐藏的元素,和输入订单号的地方,返回输入下一个订单号的地方。整个程序走完。
         if 'end.jpg' in rootlist:
             closepo = browser.find_element_by_xpath("//*[@id='po_info_box']/div[1]/div/button[3]/i")
             ActionChains(browser).move_to_element(closepo).click().perform()
             os.remove(r'D:\autoupload\uploadpic\end.jpg')
             showhide = browser.find_element_by_xpath("//*[@id='row_inspect_general']/div[1]/div[3]/button[1]")
             ActionChains(browser).move_to_element(showhide).click().perform()
             print('将要退出这个订单。')
             break

十四. 测试

通过每个阶段的测试,代码运行比较顺畅,能够完成我需要的任务。

十五.后记

这段脚本我总共花了17天写完。写到这里的时候,我已经被通知到总公司报道裁员了。准备好的代码现在也用不上了,是不是有点搞笑?不过我不这样认为,因为本例代码所使用的方法,无论在哪里都可以用上,只过是它作用的对象发生变了而已。