日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

看Python小白如何在十天內(nèi)學(xué)會獨立爬取QQ無損音樂

 豆寶有蟲吃 2019-08-09

所以這里將創(chuàng)建3個文件夾,分別用于存放這三種音樂文件。

新建一個名為download_qqMusic_by_songname.py的模塊文件,在其中添加如下代碼▼:

1import os
2
3# 創(chuàng)建歌曲下載目錄,3個品質(zhì)音樂文件分開存放
4DOWNLOAD_DIRS = ['D:/qqMusic/單曲/' + x for x in ['HQ', 'SQ', 'VQ']]
5for download_dir in DOWNLOAD_DIRS:
6 if not os.path.exists(download_dir):
7 os.makedirs(download_dir)

代碼注解>>

Line1:導(dǎo)入內(nèi)置os模塊。

Line4:變量DOWNLOAD_DIRS存儲3個目錄路徑名,因其在后面多處(包括函數(shù)內(nèi)部)會用到,所以應(yīng)聲明為“公共變量”,而Python中一般使用全大寫字母來命名公共變量。

后面是一個列表推導(dǎo)式,關(guān)于它的具體用法一會再提。

這里變量DOWNLOAD_DIRS得到的值是:

1['D:/qqMusic/單曲/HQ', 'D:/qqMusic/單曲/SQ', 'D:/qqMusic/單曲/VQ']

Line5~7:使用一個for循環(huán)語句來自動創(chuàng)建文件夾

<Tips>: 如不明白,可回顧《Day4》中 4.6.2 文件夾操作 小節(jié)的內(nèi)容。

如果執(zhí)行上面的代碼,便會在D:盤目錄下自動生成3個文件夾(如下圖▼):

看Python小白如何在十天內(nèi)學(xué)會獨立爬取QQ無損音樂

▲<上圖>QQ音樂_代碼編寫_創(chuàng)建下載目錄

下面再看看什么是 列表推導(dǎo)式 ?

6.2 列表推導(dǎo)式

列表推導(dǎo)式亦稱“列表解析”,是一種能按照一定規(guī)則從序列中生成新列表的方法。

而這個「規(guī)則」可以是運算調(diào)用方法嵌套函數(shù)等等復(fù)雜表達(dá)式,還可使用if語句對結(jié)果進(jìn)行過濾。

它是Python語法中既簡單方便,且非常有特色的用法,因為它最終只有一行表達(dá)式,無論其內(nèi)部復(fù)雜程度如何。

同時,你也可簡單理解它為for循環(huán)語句的衍生用法。

基本用法:

1# range(5)是由0~4整數(shù)組成的list,對其每個元素計算2次冪后生成一個新的list
2>>> [x**2 for x in range(5)]
3[0, 1, 4, 9, 16]
4
5# 對其每個元素乘以2并加1后生成一個新的list
6>>> [x*2+1 for x in range(5)]
7[1, 3, 5, 7, 9]

這里的x是約定俗成的變量名,當(dāng)然你也可換成其他字符。

改變元素數(shù)據(jù)類型:

1# range(5)中元素為數(shù)字,生成新list中元素類型變?yōu)樽址?br>2>>> ['a'+str(x) for x in range(5)]
3['a0', 'a1', 'a2', 'a3', 'a4']
4
5# range(5)中元素為數(shù)字,生成新list中元素類型變?yōu)榱斜?br>6>>> [[x, x*-3] for x in range(5)]
7[[0, 0], [1, -3], [2, -6], [3, -9], [4, -12]]

對元素調(diào)用方法:

1# 刪除原list中元素頭尾的空格
2>>> food = [' 米飯 ', ' 面條', ' 面 包 ', '漢堡 ']
3>>> [x.strip() for x in food]
4['米飯', '面條', '面 包', '漢堡']

strip()是字符串方法,用于移除字符串頭尾空格或換行符,但中間的不刪除。

用if子句過濾:

1# 從0~9中篩選偶數(shù),組成新列表
2>>> [x for x in range(10) if x%2 == 0] # 后面條件判斷也可以寫成“if not x%2”
3[0, 2, 4, 6, 8]
4
5# 篩選列表lst中小于5的元素,其值加上10后組成新列表
6>>> lst = [8, 2, 5, 1, 7, 12, 3, 20]
7>>> [x + 10 for x in lst if x < 5]
8[12, 11, 13]

上面的if子句均用在for語句之后,用于過濾篩選滿足條件的元素,新列表元素個數(shù)可能減少。

而將if...else形式子句放在for語句之前,還能實現(xiàn)根據(jù)條件對元素重新賦值,而新列表元素個數(shù)不變。如:

1# 能被3整除的元素取原值,否則取相反數(shù)
2>>> [x if x%3 == 0 else -x for x in range(10)]
3[0, -1, -2, 3, -4, -5, 6, -7, -8, 9]

多個for子句:

列表解析中可包含多個for子句,相當(dāng)于多層普通的for循環(huán)語句塊,循環(huán)順序從前至后。例:

1>>> lst1 = [2, -5, 8]
2>>> lst2 = [-1, 4, 0.6]
3# 下面的先讀取lst1第一個元素,再依次讀取lst2中三個元素;然后循環(huán)去讀取lst1第二個元素,再依次讀取lst2中三個元素。。。
4>>> [x + y for x in lst1 for y in lst2]
5[1, 6, 2.6, -6, -1, -4.4, 7, 12, 8.6]
6# 假如lst1與lst2變換位置后,結(jié)果則截然不同
7>>> [x + y for x in lst2 for y in lst1]
8[1, -6, 7, 6, -1, 12, 2.6, -4.4, 8.6]

再比如三個for子句:

1>>> lst1 = ['X1', 'X2']; lst2 = ['Y1', 'Y2']; lst3 = ['Z1', 'Z2']
2>>> [x + y + z for x in lst1 for y in lst2 for z in lst3]
3['X1Y1Z1', 'X1Y1Z2', 'X1Y2Z1', 'X1Y2Z2', 'X2Y1Z1', 'X2Y1Z2', 'X2Y2Z1', 'X2Y2Z2']

當(dāng)然,上面的也等價于這樣寫:

1>>> lst = []
2>>> for x in lst1:
3... for y in lst2:
4... for z in lst3:
5... lst.append(x + y +z)
6...
7>>> lst
8['X1Y1Z1', 'X1Y1Z2', 'X1Y2Z1', 'X1Y2Z2', 'X2Y1Z1', 'X2Y1Z2', 'X2Y2Z1', 'X2Y2Z2']

很顯然,使用列表推導(dǎo)式的寫法更簡潔、易閱讀,一行代碼全部搞定!

嵌套列表解析:

這個很容易與上面的“多個for子句”搞混淆,實際上嵌套列表解析相當(dāng)于在一個列表推導(dǎo)式的前部分結(jié)果位置處又嵌入一個列表推導(dǎo)式。

仍以上前一個例子進(jìn)行對比說明:

1>>> lst1 = [2, -5, 8]; lst2 = [-1, 4, 0.6]
2>>> [[x + y for x in lst1] for y in lst2] # 嵌套列表解析
3[[1, -6, 7], [6, -1, 12], [2.6, -4.4, 8.6]] # 結(jié)果1
4# 上前一個例子的結(jié)果如下
5>>> [x + y for x in lst1 for y in lst2] # 多個for子句的列表解析
6[1, 6, 2.6, -6, -1, -4.4, 7, 12, 8.6] # 結(jié)果2

可以看出,“結(jié)果1”是一個嵌套列表,有3個元素(每個元素又是一個包含3個元素的列表);而“結(jié)果2”是一個普通列表,有9個元素。

且在循環(huán)運算順序上,“結(jié)果1”是從后往前,即先外層后內(nèi)層;而“結(jié)果2”是從前往后

利用“嵌套列表解析”的特性,我們一行代碼即可輕松對一個矩陣進(jìn)行轉(zhuǎn)置。如:

1# 使用“嵌套列表解析”將3X4的矩陣列表轉(zhuǎn)置成4X3的矩陣列表
2>>> matrix = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34]]
3>>> [[x[i] for x in matrix] for i in range(4)]
4[[11, 21, 31], [12, 22, 32], [13, 23, 33], [14, 24, 34]]

否則,可能需下面繁瑣的多行代碼才能實現(xiàn):

1# 使用“普通for語句”將3X4的矩陣列表轉(zhuǎn)置成4X3的矩陣列表
2>>> matrix = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34]]
3>>> transposed = []
4>>> for i in range(4):
5... transposed_temp = []
6... for x in matrix:
7... transposed_temp.append(x[i])
8... transposed.append(transposed_temp)
9...
10>>> transposed
11[[11, 21, 31], [12, 22, 32], [13, 23, 33], [14, 24, 34]]

關(guān)于“列表推導(dǎo)式”,實際上還能組合、衍生出更高級的用法,只要你敢想。

比如還能有“字典推導(dǎo)式”

1# 用字典方式寫出數(shù)字1~9各自的平方和
2>>> {x: x**2 for x in range(1, 10)}
3{1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

但作為編程者,首要目的應(yīng)是實現(xiàn)功能,其次是讓代碼簡單易懂,而并非要代碼多么炫酷。

所以,我們更應(yīng)結(jié)合自身需要選擇適合的方法來達(dá)到目的。

現(xiàn)在再回頭看6.1小節(jié)中Line4的代碼▼,是不是就明白了呢?

1DOWNLOAD_DIRS = ['D:/qqMusic/單曲/' + x for x in ['HQ', 'SQ', 'VQ']]

6.3 讀取歌單文件

這里的“歌單文件”即上一章中提到的《SongsList.txt》,是一個普通的文本文檔,用于存儲我們希望搜索并下載的歌曲名稱。

類似這樣▼:

看Python小白如何在十天內(nèi)學(xué)會獨立爬取QQ無損音樂

▲<上圖>QQ音樂_代碼編寫_SongsList.txt

每一行都是自行添加的一首歌曲名稱/關(guān)鍵詞,現(xiàn)在我們要用Python從中讀取關(guān)鍵詞,并返回一個列表。

這里,定義一個名為get_keywords()的函數(shù)來實現(xiàn)以上功能。代碼如下▼:

 1# 定義函數(shù),從SongsList.txt中讀取需下載歌曲關(guān)鍵詞
2import sys
3
4def get_keywords():
5 fn = './SongsList.txt' # 在.py根目錄下創(chuàng)建.txt文件,關(guān)鍵詞以回車為分隔標(biāo)識符
6 if os.path.exists(fn):
7 with open(fn, 'r') as f: # 以“只讀”模塊打開文件
8 keywords = [x.strip() for x in f if x.strip()]
9 else:
10 print('<Error>: SongsList.txt文件不存在!')
11 sys.exit()
12 return keywords # 返回對象為字符串的列表

代碼注解>>

Line5:變量fn用于存儲歌單文檔的文件名,./表示在當(dāng)前目錄下。(你也可更換)

Line6 & Line9:對fn文件作個判斷,如果存在則讀取數(shù)據(jù);否則打印提示“不存在”,并退出程序。

Line8:變量keywords用于存放經(jīng)讀取并處理后的“關(guān)鍵詞”。后面的“列表推導(dǎo)式”實現(xiàn)提取關(guān)鍵詞并返回成列表的功能。

值得注意的是兩個strip()的使用,左邊的是對每行的“關(guān)鍵詞”刪除前后空格&換行;而右邊的是判斷每一行是否為空。

假如不加這兩個strip()會有什么影響呢?以上圖《SongsList.txt》為例:

1# 原代碼
2>>> keywords = [x.strip() for x in f if x.strip()]
3>>> keywords
4['你的酒館對我打了烊', '海闊天空', '銀河里最像的', '來自天堂的魔鬼', '等你下課']
5
6# 刪除右邊的'strip()'
7>>> keywords = [x.strip() for x in f]
8>>> keywords
9['你的酒館對我打了烊', '', '海闊天空', '銀河里最像的', '來自天堂的魔鬼', '', '等你下課', '', '']
10
11# 刪除左邊的'strip()'
12>>> keywords = [x for x in f if x.strip()]
13>>> keywords
14['你的酒館對我打了烊', '海闊天空', '銀河里最像的', '來自天堂的魔鬼', '等你下課']
15
16# 同時刪除左/右兩個'strip()'
17>>> keywords = [x for x in f]
18>>> keywords
19['你的酒館對我打了烊',
20 '',
21 '海闊天空',
22 '銀河里最像的',
23 '來自天堂的魔鬼',
24 '',
25 '等你下課',
26 '',
27 '']

Line11:sys.exit()是退出應(yīng)用程序,需要import sys模塊,見Line2。

Line12:最后return keywords函數(shù)返回keywords,是一個由“關(guān)鍵詞”組成的列表。

6.4 回顧小結(jié)

本章主要完成了2個步驟,即“創(chuàng)建下載目錄”“讀取歌單文件”的代碼編寫,并引出了”列表推導(dǎo)式“的概念。

所涉及內(nèi)容并不多,但“列表推導(dǎo)式”確實是Python非常好用的特性之一,大家可多理解、多試驗、多應(yīng)用

6.5 重點筆記

6.5.1 列表推導(dǎo)式

關(guān)于「列表推導(dǎo)式」及「字典推導(dǎo)式」的概念請參見6.2小節(jié)。

6.5.2 strip()方法

strip()方法用于移除字符串頭尾指定的字符(默認(rèn)為空白符,包括空格符、換行符 、制表符 、回車符 )或字符序列,但中間的不刪除。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多