背景

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

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

思路

参数配置

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

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)

页面分析

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

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

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

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

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

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

下载处理

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

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

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

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

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

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

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

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

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

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

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))

总结

最终实现效果如下:

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

完整代码

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"
  # T470s win7 64bit
  #url = 'https://think.lenovo.com.cn/support/driver/newdriversdownlist.aspx"external nofollow" target="_blank" href="https://github.com/keejo125/web_scraping_and_data_analysis/tree/master/Lenovo">https://github.com/keejo125/web_scraping_and_data_analysis/tree/master/Lenovo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

华山资源网 Design By www.eoogi.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
华山资源网 Design By www.eoogi.com

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。