python使用selenium实现批量文件下载
作者:keejo 发布时间:2022-09-23 15:27:08
背景
实现需求:批量下载联想某型号的全部驱动程序。
一般在做网络爬虫的时候,都是保存网页信息为主,或者下载单个文件。当涉及到多文件批量下载的时候,由于下载所需时间不定,下载的文件名不定,所以有一定的困难。
思路
参数配置
在涉及下载的时候,需要先对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)
页面分析
联想官网上每个型号的驱动下载页面如上图所示,虽然前面有一个登陆的遮罩,但是实际上并不影响点击。需要注意的是:
驱动列表,需要点击才可以显示具体的下载项目表格,否则可以找到对应元素但无法获取正确的信息
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),那么根据后缀来判断是否已完成下载,未完成的话继续等待
待下载完成,将文件重命名并剪切到开始建立的归档目录。这里需要注意的是,有些文件名中不能存在/
符号,否则会导致重命名失败,需要做一下替换。
在后期测试的时候,发现还有几个坑需要注意:
在查找最新创建的文件时,需要注意.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))
总结
最终实现效果如下:
完整代码
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)
完整代码参考:https://github.com/keejo125/web_scraping_and_data_analysis/tree/master/Lenovo
来源:https://segmentfault.com/a/1190000018450351
猜你喜欢
- requests 提供了一个叫做session类,来实现客户端和服务端的会话保持使用方法1.实例化一个session对象2.让session
- python3.4以上的版本中,是默认自带pip的。查看pip的方法下载安装好python后,进入命令行,输入pip -V,即可查看pyth
- 爱如风过 问:js如何能知道浏览者计算机或者浏览器使用的语言是繁体还是简体?如题,我想用jS检测到浏览者使用的是繁体还是简体中文,以便设置页
- 如何指定GPU训练模型Linux 查看当前服务器 GPU 的占用情况可以使用 nvidia-smi 命令,如下所示:nvidia-smi关于
- 方法1: X:\oracle\ora81\bin\wrap iname=XXX oname=XXX 方法2:9i在win2000下使用wra
- 一、python对json的支持从python2.6开始,python标准库中添加了对json的支持,操作json时,只需要import j
- 本文实例讲述了golang基于websocket实现的简易聊天室。分享给大家供大家参考,具体如下:先说点无关的,最近忙于工作没有更新博客,今
- 问题:如果一个网站拥有两个域名:domain1.com和domain2.com。在网站运营前期,主推domain1.com,但发展到中期,由
- 技巧问题 Mysql的远程连接出现"Lost connection to MySQL server during query&qu
- 1、背景介绍在采用通常的socket抓包方式下,操作系统会自动将收到包的VLAN信息剥离,导致上层应用收到的包不会含有VLAN标签信息。而l
- 一、前言在Python提供了强大的模块支持,主要体现为不仅在Python标准库中包含了大量的模块(称为标准模块),而且还有很多第三方模块,另
- 凯撒密码介绍凯撒密码是一种非常古老的加密方法,相传当年凯撒大地行军打仗时为了保证自己的命令不被敌军知道,就使用这种特殊的方法进行通信,以确保
- 费茨法则是人机交互领域里一个非常重要的法则,在10年来得到了广泛的应用。Fitts法则最基本的观点就是任何时候,当一个人用鼠标来移动鼠标指针
- 我一直很难理解Javascript语言的继承机制。它没有"子类"和"父类"的概念,也没有"
- jQuery之所以如此流行并被从大公司到个人博客的几乎每个人都广泛使用,是因为它上手和使用相当简单,而且为我们提供了一些人都不知道的相当棒的
- 本文的目的是探讨JS相关技术,并不是以杀毒为主要目的,杀毒只是为讲解一些JS做铺垫的,呵呵,文章有点长,倒杯咖啡或者清茶慢慢看,学习切勿急躁
- PHP quotemeta() 函数实例在预定义的字符前添加反斜杠:<?php$str = "Hello world. (c
- sql="select * from admin where users='"&users&&q
- XML文档因为其固有的描述性特性而趋向于变得很罗嗦。其结果是文档会由于被描述的数据增多而变得很长,而这种很大的文档会在需要同其他实体进行交换
- 1. 使用.logfile 方法#!/usr/bin/env pythonimport pexpectimport syshost=&quo