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

網(wǎng)站首頁
手機(jī)版

Python實(shí)用案例編程入門:第九章 爬蟲下載VOA每日廣播英語MP3?python中的廣播

更新時(shí)間:2024-03-30 13:55作者:小樂

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

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

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

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

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

9.2 實(shí)現(xiàn)思路這里我們簡單想象一下如何實(shí)現(xiàn)。總體思路如下:

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

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

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

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

9.3.1shutil模塊shutil模塊主要用于文件處理,比如最基本的文件操作、刪除、移動(dòng)、復(fù)制、壓縮解壓等,如果涉及到文件相關(guān)的操作,首先應(yīng)該想到這個(gè)模塊。

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

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

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()就可以相對容易地完成。同時(shí),您也可以根據(jù)自己的需要設(shè)置間隔時(shí)間。這里我們需要每天,所以設(shè)置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 模塊是一個(gè)比較實(shí)用的模塊,我們使用它打開文件并像字典一樣讀寫數(shù)據(jù)。如果有程序需要保存一些臨時(shí)數(shù)據(jù),或者數(shù)據(jù)不大,可以使用這個(gè)模塊。例如,我們在程序中使用此模塊來存儲(chǔ)最后的日期,以防止用戶再次重新輸入。

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

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 時(shí)間模塊時(shí)間模塊提供了各種與時(shí)間相關(guān)的函數(shù)。

time.asctime() 函數(shù)可以將結(jié)構(gòu)體struct_time 表示的時(shí)間轉(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ù)來達(dá)到目的。這里的輸入?yún)?shù)還可以是小數(shù),表示更精確的睡眠時(shí)間。我們將使用此函數(shù)進(jìn)行必要的等待,以確保另一件事完成。

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

導(dǎo)入時(shí)間time.strftime('%Y%m%d',time.localtime(time.time()))'20190714' time.strftime('%Y-%m-%d')'2019-07-14 '另一個(gè)常見的操作是使用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)置模塊,不需要單獨(dú)安裝。

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

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

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

sys.implementation 查看當(dāng)前運(yùn)行的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 標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和錯(cuò)誤的解釋器。

9.3.6 os 模塊os 模塊是一個(gè)比較常用的模塊。從名字就可以看出它與操作系統(tǒng)有關(guān)。例如,當(dāng)需要獲取當(dāng)前工作目錄時(shí),可以使用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)絡(luò)模塊,我們這里的程序需要先進(jìn)行用戶認(rèn)證。通過用戶名和密碼的認(rèn)證后,運(yùn)行我們的程序來訪問數(shù)據(jù)庫,并對數(shù)據(jù)庫進(jìn)行相應(yīng)的讀寫操作。

requests 模塊還可以用于登錄網(wǎng)頁。這方面將在其他相關(guān)程序示例中介紹。這里我們只關(guān)注當(dā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ù)設(shè)置為True,并在必要時(shí)為您自己的代理配置設(shè)置代理參數(shù)proxies。

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

9.4 代碼實(shí)現(xiàn)介紹完了相關(guān)模塊,我們來看看代碼是如何實(shí)現(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() 用于存儲(chǔ)日期# 定義函數(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代碼實(shí)現(xiàn)如下。

# -*-coding: utf-8 -*-'''此工具幫助每天自動(dòng)下載voa廣播。1。下載從上次到當(dāng)天的所有mp3 文件。2. export http_proxy=''如何實(shí)現(xiàn):#獲取最后一次下載的日期#準(zhǔn)備下載該時(shí)間段內(nèi)的所有mp3文件#檢查mp3的每個(gè)鏈接是否有效#如果有效則下載,或者使用txt文件代替#保存當(dāng)前日期創(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) 作為響應(yīng), 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):'''將當(dāng)前日期存儲(chǔ)為下一個(gè)開始日期''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ā)時(shí)間。

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

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

Python編程入門實(shí)踐案例:第一章Python概述以及為什么學(xué)習(xí)Python

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

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

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

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

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

Python編程入門實(shí)戰(zhàn)案例:第七章調(diào)試方法

Python實(shí)用案例編程入門:第八章如何自動(dòng)連接WIFI

為您推薦

解讀信用卡背后神秘?cái)?shù)字的含義——安全碼?信用卡安全嗎

信用卡的安全碼你知道多少?640 wx_fmt=png.jpg (13.02 KB, 下載次數(shù): 18)下載附件6 天前 上傳知識(shí) 信用卡安全碼,是信用卡在進(jìn)行網(wǎng)絡(luò)或電話交易時(shí)的一個(gè)安全代碼。它通常是印刷在信用卡上面的3或4位數(shù)字,不同類別

2024-03-30 13:46

新興支付技術(shù)將徹底變革傳統(tǒng)支付方式?注重安全性的Visa可不這么看

全球最安全的支付系統(tǒng)是什么?5月,在新加坡舉行的2018 VISA亞太區(qū)支付安全峰會(huì) (2018 Visa Asia Pacific Security Summit)上,超過60歲的Visa與其合作方們,針對全球支付領(lǐng)域最先進(jìn)的物聯(lián)網(wǎng)支付技

2024-03-30 13:32

支付數(shù)據(jù)安全是Visa推動(dòng)亞太地區(qū)數(shù)字經(jīng)濟(jì)發(fā)展的主要驅(qū)動(dòng)力(支付卡行業(yè)數(shù)據(jù)安全標(biāo)準(zhǔn))

第15屆Visa亞太區(qū)安全峰會(huì)在中國上海舉行,圍繞網(wǎng)絡(luò)安全、生物識(shí)別技術(shù)和更安全的電子商務(wù)支付展開交流上海2019年6月20日 /美通社/ -- 當(dāng)下,電子商務(wù)正以更加安全、先進(jìn)和便捷的趨勢迅猛發(fā)展。面對這一趨勢,Visa 承諾將持續(xù)致力于

2024-03-30 13:20

信用卡的安全碼是什么?有什么用?(行用卡的安全碼)

信用卡是當(dāng)今社會(huì)不可或缺的一種消費(fèi)工具,信用卡上有一串神秘的數(shù)字,這串?dāng)?shù)字就是安全碼,那么信用卡的安全碼是什么?有什么用?一、信用卡安全碼信用卡安全碼,是信用卡在進(jìn)行網(wǎng)絡(luò)或電話交易時(shí)的一個(gè)安全代碼。它通常是印刷在信用卡上面的3或4位數(shù)字,不

2024-03-30 13:14

信用卡安全碼知多少?信用卡背后的密碼了解一下

除了我們?nèi)粘K男庞每ń灰酌艽a、查詢密碼,信用卡其實(shí)還有一個(gè)密碼叫安全碼,也叫CVV碼、后三碼,這個(gè)碼相當(dāng)于我們的交易密碼,很多盜刷都是通過這個(gè)密碼完成的,所以日常要注意保護(hù)安全碼避免泄露。信用卡安全碼是什么信用卡安全碼,是信用卡在進(jìn)行網(wǎng)

2024-03-30 13:06

你的芯片卡安全嗎?這可能主要取決于你的銀行賬戶,芯片卡的安全性

知名安全網(wǎng)站 KrebsOnSecurity近日發(fā)文稱,以芯片為基礎(chǔ)的信用卡和借記卡的設(shè)計(jì),是為了讓盜刷設(shè)備或惡意軟件無法在你通過蘸取芯片而非刷卡條付款時(shí)克隆你的卡。但最近一系列針對美國商戶的惡意軟件攻擊表明,盜賊正在利用某些金融機(jī)構(gòu)實(shí)施該

2024-03-30 12:53

加載中...