Python使用selenium实现批量文件下载

背景

实现需求:批量下载联想某型号的全部驱动程序。

一般在做网络爬虫的时候,都是保存网页信息为主,或者下载单个文件。当涉及到多文件批量下载的时候,由于下载所需时间不定,下载的文件名不定,所以有一定的困难。

思路

参数配置

在涉及下载的时候,需要先对chromedriver进行参数配置,设定默认下载目录:

1

2

3

4

5

6

7

8

global base_path

profile = {

 'download.default_directory': base_path

}

chrome_options = webdriver.ChromeOptions()

chrome_options.add_experimental_option('prefs', profile)

driver = webdriver.Chrome(executable_path='../common/chromedriver', options=chrome_options)

driver.implicitly_wait(10)

页面分析

联想官网上每个型号的驱动下载页面如上图所示,虽然前面有一个登陆的遮罩,但是实际上并不影响点击。需要注意的是:

驱动列表,需要点击才可以显示具体的下载项目表格,否则可以找到对应元素但无法获取正确的信息

1

driver_list.find_element_by_class_name('download-center_list_t_icon').click()

每个下载列表的表头建议做跳过处理

1

2

if sub_list.find_element_by_class_name('download-center_usblist_td01').text == '驱动名称':

 continue

下载处理

在页面中,找到“普通下载”的元素,点击即可下载。最终实现结果是我们希望根据网页的列表进行重命名和重新归档到文件夹,但是我们会发现如下几个问题:

  • 下载过来的文件名无法控制。
  • 依次下载的话,我们无法确认需要下载多久。并行下载的话,无法有效的区分重命名。

在网上找了很久,也没找到在下载时直接重命名的方法,所以最终选择依次下载,当每次下载完成后进行重命名和归档,思路如下:

  • 对每个驱动目录,先新建一个文件夹,如:主板
  • 点击下载后开始下载文件
  • 通过os模块,找到下载目录中所有文件,并按创建时间排序,找到最新创建的文件
  • 由于未完成的文件后缀为.crdownload(chrome),那么根据后缀来判断是否已完成下载,未完成的话继续等待

待下载完成,将文件重命名并剪切到开始建立的归档目录。这里需要注意的是,有些文件名中不能存在/符号,否则会导致重命名失败,需要做一下替换。

在后期测试的时候,发现还有几个坑需要注意:

在查找最新创建的文件时,需要注意.DS_Store文件的处理。(Mac系统,Windows则需要考虑thumbs.db

需要判断一下最新创建的文件是否为文件夹,可以通过filter函数来处理

最新文件的排序查找实现如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

def sort_file():

 # 排序文件

 dir_link = base_path

 dir_lists = list(filter(check_file, os.listdir(dir_link)))

 if len(dir_lists) == 0:

  return ''

 else:

  dir_lists.sort(key=lambda fn: os.path.getmtime(dir_link + os.sep + fn))

  return os.path.join(base_path, dir_lists[-1])

def check_file(filename):

 # 忽略系统文件

 if filename == '.DS_Store' or filename == 'thumbs.db':

  return False

 global base_path

 # 排除文件夹

 return os.path.isfile(os.path.join(base_path, filename))

总结

最终实现效果如下:

完整代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

import os

import time

import re

from selenium import webdriver

'''

想要学习Python?Python学习交流群:984632579满足你的需求,资料都已经上传群文件,可以自行下载!

'''

  

def sort_file():

  # 排序文件

  dir_link = base_path

  dir_lists = list(filter(check_file, os.listdir(dir_link)))

  if len(dir_lists) == 0:

    return ''

  else:

    dir_lists.sort(key=lambda fn: os.path.getmtime(dir_link + os.sep + fn))

    return os.path.join(base_path, dir_lists[-1])

  

  

def check_file(filename):

  # 忽略系统文件

  if filename == '.DS_Store' or filename == 'thumbs.db':

    return False

  global base_path

  # 排除文件夹

  return os.path.isfile(os.path.join(base_path, filename))

  

  

def download_drivers(url):

  global base_path

  profile = {

    'download.default_directory': base_path

    }

  chrome_options = webdriver.ChromeOptions()

  chrome_options.add_experimental_option('prefs', profile)

  driver = webdriver.Chrome(executable_path='../common/chromedriver', options=chrome_options)

  driver.implicitly_wait(10)

  driver.get(url)

  driver_lists = driver.find_elements_by_class_name('dlist-item')

  for driver_list in driver_lists:

    # 提取中文及英文字母

    title = ''.join(re.findall(r'[\u4e00-\u9fa5a-zA-Z]+', driver_list.text))

    temp_path = './drivers/' + title

    if not os.path.exists(temp_path):

      os.mkdir(temp_path)

    driver_list.find_element_by_class_name('download-center_list_t_icon').click()

    sub_lists = driver_list.find_elements_by_tag_name('tr')

    for sub_list in sub_lists:

      try:

        if sub_list.find_element_by_class_name('download-center_usblist_td01').text == '驱动名称':

          continue

        else:

          sub_title = sub_list.find_element_by_class_name('download-center_usblist_td01').\

            find_element_by_tag_name('a').get_attribute('title').replace('/', '_')

          print('开始下载:' + sub_title)

          sub_list.find_element_by_link_text('普通下载').click()

          # 等待开始下载

          time.sleep(2)

          while True:

            oldname = sort_file()

            file_type = oldname.split('.')[-1]

            if oldname != '' and file_type != 'crdownload':

              print('下载已完成')

              break

            else:

              print("等待下载。。。")

              time.sleep(10)

          newnamne = temp_path + os.sep + sub_title + '.' + file_type

          os.rename(oldname, newnamne)

          print('归档成功')

      except Exception as e:

        print(e)

        continue

  print('下载结束')

  driver.quit()

  

  

if __name__ == '__main__':

  base_path = './drivers'

  if not os.path.exists(base_path):

    os.mkdir(base_path)

    print('创建drivers文件夹')

  # T470s win10 64bit

  url = "https://think.lenovo.com.cn/support/driver/newdriversdownlist.aspx?categoryid=12832&CODEName=ThinkPad%20T470s&SearchType=1&wherePage=1&SearchNodeCC=ThinkPad%20T470s"

  # T470s win7 64bit

  #url = 'https://think.lenovo.com.cn/support/driver/newdriversdownlist.aspx?categoryid=12832&CODEName=ThinkPad%20T470s&SearchType=1&wherePage=1&SearchNodeCC=ThinkPad%20T470s&osid=26'

  # T460s win10 64bit

  # url = 'https://think.lenovo.com.cn/support/driver/newdriversdownlist.aspx?yt=pt&categoryid=12358&CODEName=ThinkPad%20T460s&SearchType=0&wherePage=2&osid=42'

  # T460s win7 64bit

  # url = 'https://think.lenovo.com.cn/support/driver/newdriversdownlist.aspx?yt=pt&categoryid=12358&CODEName=ThinkPad%20T460s&SearchType=0&wherePage=2&osid=26'

  # T450s win10 64bit

  # url = 'https://think.lenovo.com.cn/support/driver/newdriversdownlist.aspx?yt=pt&categoryid=12002&CODEName=ThinkPad%20T450s&SearchType=0&wherePage=2&osid=42'

  download_drivers(url)

​现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:485187702【暗号:csdn11】

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!【100%无套路免费领取】

  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值