整个流程大致如下:
1、首先需要在http://chromedriver.storage.googleapis.com/index.html
中下载chrome浏览器版本对应的驱动文件,可以在浏览器【设置】中进行查看。
2、然后把下载下来的chromedriver.exe文件移动到Python目录,如果没有添加到path路径,也可以在python代码中指定chromedrive的路径。
3、访问网站——登录——模拟点击标签进入页面——更改时间范围查询数据——模拟点击进行下载文件——文件改名。
一、引用的包
from selenium import webdriver
import time
import os
其中,selenium.webdriver用于操作网页,time是防止网页元素加载过慢影响代码正常读取。
二、加载页面进行登录
opt = webdriver.ChromeOptions() #创建浏览
driver = webdriver.Chrome(options=opt) #创建浏览器对象
driver.get('输入网址')
time.sleep(0.1) #加载等待
# 登录
driver.find_element_by_xpath("/html/body/form/div[2]/div[1]/div[3]/input").send_keys("输入账号")
driver.find_element_by_xpath("/html/body/form/div[2]/div[1]/div[4]/input[3]").send_keys("输入密码")
driver.find_element_by_xpath("/html/body/form/div[2]/div[1]/div[5]/input[3]").click()
创建实例访问网站,输入账号密码然后点击登录按钮。
三、更改Frame,点击导航栏
driver.switch_to.frame('leftFrame')
driver.find_element_by_xpath('/html/body/form/div/div/div/div[2]/ul/li[4]').click()
time.sleep(0.1)
driver.find_element_by_xpath('/html/body/form/div/div/div/div[2]/ul/li[5]').click()
time.sleep(0.1)
driver.find_element_by_xpath('/html/body/form/div/div/div/div[2]/ul/li[6]').click()
time.sleep(0.1)
第一次爬的时候没有注意到有frame框架,因此需要先用switch_to.frame()更改到目标frame。传入frame的ID和name都可以。
其实这里可以写一个循环去读取,因为标签后面list是严格的数组递增。
三、进入指定页面调整数据时间范围
# 调整时间范围
driver.switch_to.default_content()
driver.switch_to.frame('mainFrame')
date_st_path = driver.find_element_by_xpath('/html/body/form/div/div/div[2]/div[2]/ul/li[2]/input')
date_ed_path = driver.find_element_by_xpath('/html/body/form/div/div/div[2]/div[2]/ul/li[4]/input')
date_st = 'arguments[0].value="2022/01/01"'
date_ed = 'arguments[0].value="2022/12/31"'
driver.execute_script(date_st, date_st_path)
driver.execute_script(date_ed, date_ed_path)
driver.find_element_by_xpath("/html/body/form/div/div/div[3]/table/tbody/tr[1]/td/a[1]").click()
由于前一步我们更改了frame,需要先选择到default_content然后再重新选择frame。然后获取开始日期和结算日期的Xpath,用execute_script更改标签属性的值。
四、文件下载,文件改名
1.由于网页文件下载设计的特殊性,每条订单记录的附件都需要手动勾选,然后再点击批量下载,而且下载的文件都是整合到zip包,只能下载完成再更改文件名。
2.如果不小心点到其他订单的附件,再点击批量下载都会压缩到一个zip包,所以需要每次只勾选一条订单的所有附件,然后取消掉上一条订单的勾选,再点击批量下载。
3.由于文件都是以temp.zip命名,当下载超过temp (100).zip之后就不再以数字命名了,因此需要不超过100条来进行批量改名。
# 文件目录
file_name_old = r'D:\Downloads\temp.zip' # 文件下载路径
file_path_old = os.path.dirname(file_name_old)
file_arr = []
fg = 1
ff = 0
yc_fg = 0
# 进行下载
while fg:
for i in range(3, 13):
try:
# 因为存在重复的订单号,所以文件新的命名是由订单号+物流信息拼接而成。
# 同时物流信息中存在异常符号 /\,因此需要先去掉,否则无法更改文件名。
file_name_new = driver.find_element_by_xpath(
'/html/body/form/div/div/div[3]/table/tbody/tr[' + str(i) + ']/td[2]').text + \
'_' + str(driver.find_element_by_xpath(
'/html/body/form/div/div/div[3]/table/tbody/tr[' + str(i) + ']/td[5]').text).replace('/','') + '.zip'
except Exception as r:
yc_fg += 1
file_name_new = '异常文件' + str(yc_fg) + '号.zip'
# file_path_new = os.path.join(file_path_old, file_name_new)
file_arr.append(file_name_new)
for j in range(2, 16):
'/html/body/form/div/div/div[3]/table/tbody/tr[3]/td[14]/input'
path = '/html/body/form/div/div/div[3]/table/tbody/tr[' + str(i) + ']/td[' + str(j) + ']/input'
try:
if i > 3:
path_old = '/html/body/form/div/div/div[3]/table/tbody/tr[' + str(i - 1) + ']/td[' + str(
j) + ']/input'
driver.find_element_by_xpath(path_old).click()
except Exception as x:
s = 0
try:
driver.find_element_by_xpath(path).click()
except Exception as e:
s = 0
# 点击下载
driver.find_element_by_xpath('/html/body/form/div/div/div[3]/table/tbody/tr[1]/td/a[2]').click()
ff += 1
if ff > 90:
time.sleep(10)
for i in range(len(file_arr)):
try:
if i == 0:
file_name_old = os.path.join(file_path_old, 'temp.zip')
else:
name_old = 'temp (' + str(i) + ').zip'
file_name_old = os.path.join(file_path_old, name_old)
file_name_new = os.path.join(file_path_old, file_arr[i])
os.rename(file_name_old, file_name_new)
except Exception as ss:
s = 0
file_arr = []
ff = 0
try:
driver.find_element_by_xpath('/html/body/form/div/div/div[3]/table/tbody/tr[13]/td/div[2]/div[1]/a[3]').click()
except Exception as r:
fg = 0
# 延时20s是防止存在“文件没有下载完就更改文件名”出现的报错。
time.sleep(20)
for i in range(len(file_arr)):
if i == 0:
file_name_old = os.path.join(file_path_old, 'temp.zip')
else:
name_old = 'temp (' + str(i) + ').zip'
file_name_old = os.path.join(file_path_old, name_old)
file_name_new = os.path.join(file_path_old, file_arr[i])
os.rename(file_name_old, file_name_new)
总结:
1、首先是下载了和浏览器版本冲突的驱动;
2、其次是登录之后需要切换frame,不然会一直报找不到目标element的错误;
3、接着就出现了页面加载不够快,导致代码不能正常读取标签;
4、然后是循环点击的时候经常出现漏点击的情况,经debug发现是try catch直接跳过了;
5、后面在文件改名的时候又存在循环边界不够,导致有些文件没有覆盖到;