红菊直播官方版-红菊直播免费版app下载-红菊直播永久免费版下载

Python實用案例編程入門:第九章 爬蟲下載VOA每日廣播英語MP3

更新時間:2024-08-13 05:35作者:小樂

本章的主題是介紹如何利用爬蟲的方法下載VOA每日廣播的英文MP3文件,解決我們生活中遇到的實際問題。

9.1 應解決什么問題?首先介紹一個練習英語聽力的好網(wǎng)站:https://learningenglish.voanews.com/。它有滿足不同聆聽需求的部分。每天還有30分鐘的廣播,可以幫助我們練習沉浸式聽力。是美式英語播音員,速度比較慢,適合學習者練習。還有一些視頻教程,我個人覺得不錯,推薦給大家(缺點是需要通過代理訪問網(wǎng)站)。

我在使用它時遇到的一個問題是我每次都在線收聽。在手機上聽會比較麻煩,所以就想過下載,但又覺得一一點擊下載太麻煩了。所以我決定寫一個Python程序來幫助我下載它。這就是了解如何使用Python的好處。

在開始一個實際的程序之前,我們需要思考我們的程序想要實現(xiàn)什么功能?

從上述網(wǎng)站下載mp3文件;下載設定日期內(nèi)所有播放的mp3文件;支持在命令行傳遞開始和結(jié)束日期,如20190101 20190530;如果在命令行上傳遞日期,則該日期將用作開始日期,當天的時間用作截止日期;如果命令行中未輸入日期,則將下載上次到當天之間的mp3 文件。如果沒有最后一次,則只下載當天的mp3文件;代理設置,我們?nèi)绾问褂么恚枰_設置對應的url和端口,然后將其賦給下載功能中使用的代理參數(shù);基于我們想要實現(xiàn)的功能,我們開始思考如何實現(xiàn)。

9.2 實現(xiàn)思路這里我們簡單想象一下如何實現(xiàn)??傮w思路如下:

解析參數(shù),確定下載日期,存入列表;將下載日期和下載鏈接拼接成下載鏈接;如果鏈接合法,則下載,否則創(chuàng)建一個以日期為名稱的txt文件,并將下載鏈接存儲在其中;保存當天的日期;需要先解析下載地址,先手動找到下載地址。

http://av.voanews.com/clips/VLE/2019/06/15/20190615-003000-VLE122-program_hq.mp3 download=1,就是這個樣子,可以看到里面包含了2019/06/15/20190615這樣的字符string,我可以推斷任意一天的下載地址只是另一個固定字符串加上日期。隨機找了一天去驗證一下,發(fā)現(xiàn)確實如此。那么就簡單了,不需要爬行。

下載過程中,由于每個文件大約30MB,下載需要幾秒鐘的時間(當然也取決于網(wǎng)速),所以我們的下載必須使用流式下載,所以在下面的函數(shù)中,stream=True就是使用流式下載下載中。

def download_file(file_url, file_name):'''下載文件'''with requests.get(file_url, stream=True, proxies=None) 作為響應, open(file_name, 'wb') as local_file:shutil.copyfileobj(response.raw ,local_file)9.3 相關模塊的安裝及介紹本節(jié)將介紹程序中用到的相關模塊。

9.3.1shutil模塊shutil模塊主要用于文件處理,比如最基本的文件操作、刪除、移動、復制、壓縮和解壓等,如果涉及到文件相關的操作,首先應該想到這個模塊。

我們這里使用該模塊的copyfileobject方法將流數(shù)據(jù)對象的內(nèi)容復制到我們創(chuàng)建的MP3文件中。

def download_file(file_url, file_name):'''下載文件'''with requests.get(file_url, stream=True, proxies=None) 作為響應, open(file_name, 'wb') as local_file:shutil.copyfileobj(response.raw , local_file) 9.3.2 datetime 模塊datetime 模塊用于處理與日期相關的事務。這里我們將使用該模塊的strptime() 接口來構(gòu)造一個日期字符串。

def handle_parameters(parameters):end_date=datetime.datetime.strptime(time.strftime('%Y%m%d',time.localtime(time.time())), '%Y%m%d')begin_date=end_date #begin_date=datetime.datetime.strptime('20190701', '%Y%m%d')if len(parameters)=3:begin_date=datetime.datetime.strptime(parameters[1], '%Y%m%d') if is_valid_data(parameters[1]) else exit(-1)end_date=datetime.datetime.strptime(parameters[2], '%Y%m%d') if is_valid_data(parameters[2]) else exit(-1) elif len(parameters)=2:begin_date=datetime.datetime.strptime(parameters[1], '%Y%m%d') if is_valid_data(sys.argv[1]) else exit(-1)else:#if 有上次,我們使用它作為begin_date,否則我們使用end_date as begin_date.begin_date=get_last_date(last_date_file, begin_date)return begin_date, end_date 在我們的程序中,我們需要獲取起始日期范圍內(nèi)的所有日期字符串。如果人工構(gòu)造起來非常困難,但是基于datetime的timedelta()就可以相對容易地完成。同時,您也可以根據(jù)自己的需要設置間隔時間。這里我們需要每天,所以設置days=1。

def get_file_list(begin_date, end_date):'''獲取我們要下載的所有文件''' date_list=[] while begin_date=end_date: date_dir=begin_date.strftime('%Y/%m/%d/') date_str=begin_date.strftime('%Y%m%d') date_list.append(date_dir+date_str) begin_date +=datetime.timedelta(days=1)return date_list9.3.3 shelve 模塊shelve 模塊是一個比較實用的模塊,我們使用它打開文件并像字典一樣讀寫數(shù)據(jù)。如果有程序需要保存一些臨時數(shù)據(jù),或者數(shù)據(jù)不大,可以使用這個模塊。例如,我們在程序中使用此模塊來存儲最后的日期,以防止用戶再次重新輸入。

def store_current_date(file, date):'''將當前日期存儲為下一個開始日期''' s=shelve.open(file, writeback=True) s[last_date_key]=date s.close() 上面的代碼是什么我們使用來存儲日期,下面看看當我們需要使用日期時如何獲取日期。

def get_last_date(file, default_date):'''從文件中獲取最后日期''' date=default_date if os.path.exists(file): s=shelve.open(file, writeback=True) last_date=s[last_date_key] s.close() date=datetime.datetime.strptime(last_date, '%Y%m%d')return date9.3.4 time 模塊time 模塊提供各種與時間相關的函數(shù)。

time.asctime() 函數(shù)可以將結(jié)構(gòu)體struct_time 表示的時間轉(zhuǎn)換為類似'Sun Jun 19 13:31:15 1994' 的字符串。我們可以通過time.localtime()函數(shù)獲取結(jié)構(gòu)體struct_time。

time.sleep()函數(shù)的輸入?yún)?shù)單位為秒。如果需要掛起線程,可以通過調(diào)用該函數(shù)來達到目的。這里的輸入?yún)?shù)還可以是小數(shù),表示更精確的睡眠時間。我們將使用此函數(shù)進行必要的等待,以確保另一件事完成。

time.strftime() 函數(shù)也用于格式化時間。

導入時間time.strftime('%Y%m%d',time.localtime(time.time()))'20190714' time.strftime('%Y-%m-%d')'2019-07-14 '另一個常見的操作是使用time.strptime() 接口來確定給定的字符串是否是有效的日期。

def is_valid_data(date_str):'''檢查日期字符串是否有效'''try: time.strptime(date_str, '%Y%m%d') return True except:return False9.3.5 sys 模塊sys 模塊是內(nèi)置模塊,不需要單獨安裝。

sys模塊提供了對Python解釋器使用的一些變量的訪問,并且可以進行一些修改,比如讀取和修改環(huán)境變量PATH,并提供了一定的與解釋器交互的函數(shù),以便我們的程序可以與解釋器進行交互。

例如sys.argv會將命令行參數(shù)以列表的形式傳遞給Python腳本,sys.argv[0]是腳本的名稱,sys.argv[1]是第一個參數(shù),以此類推。

sys.exit()表示退出程序,也可以帶參數(shù)表示退出碼。如果有其他程序調(diào)用該程序,則可以通過返回的數(shù)字確定被調(diào)用程序的退出原因。

sys.implementation 查看當前運行的Python解釋器的版本信息。

sys.implementationnamespace(cache_tag='cpython-36', hexversion=50726384, name='cpython', version=sys.version_info(major=3,minor=6,micro=5,releaselevel='final',serial=0) )sys.stdin、sys.stddout、sys.stderr 標準輸入、標準輸出和錯誤的解釋器。

9.3.6 os 模塊os 模塊是一個比較常用的模塊。從名字就可以看出它與操作系統(tǒng)有關。例如,當需要獲取當前工作目錄時,可以使用getcwd()接口。您還可以輕松分離路徑的文件夾部分和文件名部分。

import os os.getcwd()'C:\\Users\\just right' os.path.abspath('.')'C:\\Users\\just right' path=r'E:\第09章爬蟲每日下載voa廣播英文MP3文件\auto-download-voa-broadcast.py' os.path.split(path)('E: \\第09章爬蟲下載voa每日廣播英文MP3文件', 'auto-download-voa-broadcast.py ') 我們這里的程序?qū)⑹褂胦s 模塊來判斷文件是否存在。代碼如下。

path=r'E:\第09章爬蟲下載voa每日廣播英文MP3文件\auto-download-voa-broadcast.py' os.path.exists(path)True9.3.7 requests模塊requests模塊是用于訪問網(wǎng)絡模塊,我們這里的程序需要先進行用戶認證。通過用戶名和密碼的認證后,運行我們的程序來訪問數(shù)據(jù)庫,并對數(shù)據(jù)庫進行相應的讀寫操作。

requests 模塊還可以用于登錄網(wǎng)頁。這方面將在其他相關程序示例中介紹。這里我們只關注當前示例程序需要使用的內(nèi)容。

以下代碼片段是我們程序中用于確定鏈接有效性的函數(shù)。我們將鏈接和代理參數(shù)傳遞給get接口,然后使用接口返回的文本來判斷鏈接是否有效。在我們的示例中,如果鏈接無效,頁面文本將包含字符串“404 - 未找到文件或目錄”。

def is_valid_link(file_url, invalid_msg):'''檢查mp3_url 是否有效''' text='' return True with requests.get(file_url, proxies=http_proxies) as response: print(response.text) text=response.textreturn True if invalid_msg in text else False 以下函數(shù)展示了如何通過requests 模塊下載文件,將Stream 參數(shù)設置為True,并在必要時為您自己的代理配置設置代理參數(shù)proxies。

def download_file(file_url, file_name):'''下載文件'''with requests.get(file_url, stream=True, proxies=None) 作為響應, open(file_name, 'wb') as local_file:shutil.copyfileobj(response.raw ,本地文件)

9.4 代碼實現(xiàn)介紹完了相關模塊,我們來看看代碼是如何實現(xiàn)的。

9.4.1 編寫偽代碼我們首先編寫必要的偽代碼來了解程序的整體結(jié)構(gòu)。

# 定義函數(shù)is_valid_link 來判斷鏈接是否有效# 定義函數(shù)is_valid_date 來判斷給定的字符是否是有效日期# 定義函數(shù)download() 來下載文件# 定義函數(shù)get_file_list() 來獲取一個時間內(nèi)的每一天給定日期范圍日期字符串# 定義函數(shù)get_last_date() 用于從配置文件中獲取最后日期# 定義函數(shù)store_current_date() 用于存儲日期# 定義函數(shù)handle_parameters() 用于處理程序的參數(shù)if '__main__'==__name__: 利用handle_parameters()處理程序參數(shù)通過get_file_list()獲取日期字符串列表,遍歷日期字符串列表,并將其轉(zhuǎn)換為url鏈接。如果url有效,則下載,否則創(chuàng)建txt文件,記錄失敗原因。 9.4.2 Python代碼Python代碼實現(xiàn)如下。

# -*-coding: utf-8 -*-'''此工具幫助每天自動下載voa廣播。1。下載從上次到當天的所有mp3 文件。2. export http_proxy=''如何實現(xiàn):#獲取最后一次下載的日期#準備下載該時間段內(nèi)的所有mp3文件#檢查mp3的每個鏈接是否有效#如果有效則下載,或者使用txt文件代替#保存當前日期創(chuàng)建于Fri Jun 15 14:17:40 2019 @author: ggang.liu'''import Shutilimport datetimeimport shelveimport timeimport sysimport osimport requestsserver_error='404 - 文件或目錄未找到'last_date_file='last_date'last_date_key='date'url_template='http://av .voanews.com/clips/VLE/{ 0}-003000-VLE122-program_hq.mp3 download=1'def is_valid_link(file_url, invalid_msg):'''檢查mp3_url 是否有效'''text=''return Truewith requests .get(file_url, proxies=http_proxies) as response:print(response.text)text=response.textreturn True if invalid_msg in text else Falsedef is_valid_data(date_str):'''檢查日期字符串是否有效'''try:time.strptime(date_str , '%Y%m%d') return True except:return Falsedef download_file(file_url, file_name):'''下載文件'''with requests.get(file_url, stream=True, proxies=None) 作為響應, open(file_name, 'wb') as local_file:shutil.copyfileobj(response .raw, local_file)def get_file_list(begin_date, end_date):'''獲取我們要下載的所有文件'''date_list=[]while begin_date=end_date:date_dir=begin_date.strftime( '%Y/%m/%d/')date_str=begin_date.strftime('%Y%m%d')date_list.append(date_dir+date_str)begin_date +=datetime.timedelta(days=1)return date_listdef get_last_date( file, default_date):'''從文件中獲取最后日期'''date=default_dateif os.path.exists(file):s=shelve.open(file, writeback=True)last_date=s[last_date_key]s.close() date=datetime.datetime.strptime(last_date, '%Y%m%d')return datedef store_current_date(file, date):'''將當前日期存儲為下一個開始日期''s=shelve.open(file, writeback=True)s[last_date_key]=日期.close()def handle_parameters(parameters):end_date=datetime.datetime.strptime(time.strftime('%Y%m%d',time.localtime(time.time())) ), '%Y%m%d' )begin_date=end_date#begin_date=datetime.datetime.strptime('20190701', '%Y%m%d')if len(參數(shù))=3:begin_date=datetime.datetime.strptime(參數(shù)[1], '%Y%m %d') if is_valid_data(parameters[1]) else exit(-1)end_date=datetime.datetime.strptime(parameters[2], '%Y%m%d') if is_valid_data(parameters[2]) else exit (-1)elif len(parameters)=2:begin_date=datetime.datetime.strptime(parameters[1], '%Y%m%d') if is_valid_data(sys.argv[1] ]) else exit(-1)else:# 如果有最后一次,則將其用作begin_date,否則將end_date 用作begin_date.begin_date=get_last_date(last_date_file, begin_date)return begin_date, end_dateif '__main__'==__name__:begin_date, end_date=handle_parameters(sys.argv)#獲取日期listdate_list=get_file_list(begin_date, end_date)print(date_list)for date_list中的日期:file_url=url_template.format(date)if is_valid_link(file_url, server_error):print('正在下載:' + file_url)download_file( file_url, 'voa_broadcast_'+date[-8: ]+'.mp3')else:with open(date[-8:]+'.txt', 'w') as f:f.write(file_url)9.5 本章小結(jié)一般來說,思路比較簡單,就是構(gòu)造要下載的日期作為下載鏈接,一一下載。 Python是一門非常好的語言,可以極大的幫助我們節(jié)省開發(fā)時間。

學以致用才是正確的出路。這也是編程的樂趣所在。

歡迎關注、轉(zhuǎn)發(fā)、點贊

Python編程入門實踐案例:第一章Python概述以及為什么學習Python

Python編程入門實踐案例:第二章字符串

Python實用案例編程簡介:第3章列表和元組

Python實用案例編程入門:第4章字典和文件

Python實用案例編程入門:第6章控制流語句

Python實用案例編程入門:第五章函數(shù)和類

Python實用案例編程入門:第七章調(diào)整方法

Python實用案例編程入門:第八章如何自動連接WIFI

為您推薦

高考與未來:弗吉尼亞理工大學的教育優(yōu)勢(慎重選擇弗吉尼亞理工)

弗吉尼亞理工大學的教育優(yōu)勢弗吉尼亞理工大學(Virginia Tech)是一所位于美國東岸弗吉尼亞州的著名公立大學,成立于1872年,現(xiàn)已發(fā)展成弗吉尼亞州內(nèi)規(guī)模最大、提供學位最多的高等教育機構(gòu)之一 1。以下是弗吉尼亞理工大學的一些教育優(yōu)勢:

2024-08-13 05:34

「擇校解讀」弗吉尼亞理工大學(Virginia Tech)院校指南,弗吉尼亞理工學院怎么樣

擇校解讀系列是普加斯留學打造的美國院校解讀欄目,通過對各大院校的不同領域和板塊分析,為大家提供更為直觀和多樣的大學資訊,幫助大家更全面地了解美國院校情況,為擇校打好基礎。弗吉尼亞理工大學(Virginia Tech)是一所以工科為主的頂尖公

2024-08-13 05:34

弗吉尼亞理工大學:高考后留學美國的明智之選

弗吉尼亞理工大學:高考后留學美國的明智之選弗吉尼亞理工大學(Virginia Tech),全稱為弗吉尼亞理工學院及州立大學,是一所位于美國東岸弗吉尼亞州的著名公立大學。學校成立于1872年,設有農(nóng)學和生命科學學院、建筑和城市研究學院、藝術和

2024-08-13 05:33

揭秘弗吉尼亞理工大學的高考錄取標準 弗吉尼亞理工大學錄取率

弗吉尼亞理工大學的高考錄取標準弗吉尼亞理工大學(Virginia Tech)是一所位于美國弗吉尼亞州的公立研究型大學,成立于1872年,以其工程學、科學和技術為主。以下是關于弗吉尼亞理工大學高考錄取標準的介紹:錄取條件GPA要求弗吉尼亞理工

2024-08-13 05:33

高考生必知:弗吉尼亞理工大學的申請流程 弗吉尼亞理工大學申請條件

弗吉尼亞理工大學的申請流程弗吉尼亞理工大學(Virginia Tech)是一所位于美國弗吉尼亞州的公立研究型大學,成立于1872年,是一所具有悠久歷史的美國大學。以下是弗吉尼亞理工大學的申請流程:第一步:參加標準化考試申請者需要參加標準化考

2024-08-13 05:32

山東理工大學新聘了倆院長,他們都是啥來歷?(山東理工大學院長書記)

3月12日,山東理工大學發(fā)布了《山東理工大學關于陶東平張琳兩位工作人員職務任免的通知》,聘任陶東平為資源與環(huán)境工程學院院長;張琳為法經(jīng)濟學研究院院長。其中,法經(jīng)濟學研究院為新設,這倆新院長到底啥來歷,看一看簡歷才發(fā)現(xiàn),倆人都不簡單,都是學校

2024-08-13 05:32

加載中...