python使用selenium實現(xiàn)批量文件下載
背景
實現(xiàn)需求:批量下載聯(lián)想某型號的全部驅動程序。
一般在做網(wǎng)絡爬蟲的時候,都是保存網(wǎng)頁信息為主,或者下載單個文件。當涉及到多文件批量下載的時候,由于下載所需時間不定,下載的文件名不定,所以有一定的困難。
思路
參數(shù)配置
在涉及下載的時候,需要先對chromedriver進行參數(shù)配置,設定默認下載目錄:
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)
頁面分析

聯(lián)想官網(wǎng)上每個型號的驅動下載頁面如上圖所示,雖然前面有一個登陸的遮罩,但是實際上并不影響點擊。需要注意的是:
驅動列表,需要點擊才可以顯示具體的下載項目表格,否則可以找到對應元素但無法獲取正確的信息
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
下載處理
在頁面中,找到“普通下載”的元素,點擊即可下載。最終實現(xiàn)結果是我們希望根據(jù)網(wǎng)頁的列表進行重命名和重新歸檔到文件夾,但是我們會發(fā)現(xiàn)如下幾個問題:
- 下載過來的文件名無法控制。
- 依次下載的話,我們無法確認需要下載多久。并行下載的話,無法有效的區(qū)分重命名。
在網(wǎng)上找了很久,也沒找到在下載時直接重命名的方法,所以最終選擇依次下載,當每次下載完成后進行重命名和歸檔,思路如下:
- 對每個驅動目錄,先新建一個文件夾,如:主板
- 點擊下載后開始下載文件
- 通過
os模塊,找到下載目錄中所有文件,并按創(chuàng)建時間排序,找到最新創(chuàng)建的文件 - 由于未完成的文件后綴為
.crdownload(chrome),那么根據(jù)后綴來判斷是否已完成下載,未完成的話繼續(xù)等待

待下載完成,將文件重命名并剪切到開始建立的歸檔目錄。這里需要注意的是,有些文件名中不能存在/符號,否則會導致重命名失敗,需要做一下替換。
在后期測試的時候,發(fā)現(xiàn)還有幾個坑需要注意:
在查找最新創(chuàng)建的文件時,需要注意.DS_Store文件的處理。(Mac系統(tǒng),Windows則需要考慮thumbs.db)
需要判斷一下最新創(chuàng)建的文件是否為文件夾,可以通過filter函數(shù)來處理
最新文件的排序查找實現(xiàn)如下:
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): # 忽略系統(tǒng)文件 if filename == '.DS_Store' or filename == 'thumbs.db': return False global base_path # 排除文件夾 return os.path.isfile(os.path.join(base_path, filename))
總結
最終實現(xiàn)效果如下:

完整代碼
import os
import time
import re
from selenium import webdriver
'''
想要學習Python?Python學習交流群:984632579滿足你的需求,資料都已經(jīng)上傳群文件,可以自行下載!
'''
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):
# 忽略系統(tǒng)文件
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('創(chuàng)建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
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Python中字節(jié)數(shù)組和16進制字符串轉換方式
這篇文章主要介紹了Python中字節(jié)數(shù)組和16進制字符串轉換方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06
使用Python讀取和修改Excel文件(基于xlrd、xlwt和openpyxl模塊)
本文介紹一下使用Python對Excel文件的基本操作,包括使用xlrd模塊讀取excel文件,使用xlwt模塊將數(shù)據(jù)寫入excel文件,使用openpyxl模塊讀取寫入和修改excel文件,需要的朋友可以參考下2021-11-11
最新PyCharm從安裝到PyCharm永久激活再到PyCharm官方中文漢化詳細教程
這篇文章涵蓋了最新版PyCharm安裝教程,最新版PyCharm永久激活碼教程,PyCharm官方中文(漢化)版安裝教程圖文并茂非常詳細,需要的朋友可以參考下2020-11-11
Python開發(fā)工具Pycharm的安裝以及使用步驟總結
今天給大家?guī)淼氖顷P于Python開發(fā)工具的安裝以及使用的相關知識,文章圍繞著如何使用和安裝Pycharm展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下2021-06-06

