網易雲音樂的手機客戶端有將歌詞儲存成圖片分享的功能,但是一次只能儲存一首歌。所以我用 Python 寫了個指令碼,可以將歌單裡面的所有歌曲都儲存成圖片。

還有缺陷需要彌補

GitHub - songzhi/Lrc2Img: 用Python將歌單裡的所有歌曲的歌詞儲存成圖片,使用了網易雲音樂API

使用了:

網易雲音樂的API

Pillow,requests 等模組

字型是 造字工房尚黑常規體,可以自己更改,在Img類裡的save方法的font變數裡

大概思路:

1。利用 API 獲取資訊,返回的是 Json 格式的資料,可以使用標準庫裡的 json 模組轉化成Python 內建的資料結構,其中 Json 中的 Object 轉化成了列表,所以對其進行迭代,找出其中的專輯圖片(url)、歌曲名字 id 和歌詞分別放入幾個列表中。

API 程式碼:

class

NetEase

():

cookies_filename

=

“netease_cookies。json”

def

__init__

self

):

super

()

__init__

()

self

headers

=

{

‘Host’

‘music。163。com’

‘Connection’

‘keep-alive’

‘Content-Type’

“application/x-www-form-urlencoded; charset=UTF-8”

‘Referer’

‘http://music。163。com/’

“User-Agent”

“Mozilla/5。0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537。36”

“ (KHTML, like Gecko) Chrome/33。0。1750。152 Safari/537。36”

}

self

cookies

=

dict

appver

=

“1。2。1”

os

=

“osx”

def

show_progress

self

response

):

content

=

bytes

()

total_size

=

response

headers

get

‘content-length’

if

total_size

is

None

content

=

response

content

return

content

else

total_size

=

int

total_size

bytes_so_far

=

0

for

chunk

in

response

iter_content

():

content

+=

chunk

bytes_so_far

+=

len

chunk

progress

=

round

bytes_so_far

*

1。0

/

total_size

*

100

self

signal_load_progress

emit

progress

return

content

def

http_request

self

method

action

query

=

None

urlencoded

=

None

callback

=

None

timeout

=

1

):

headers

=

{

‘Host’

‘music。163。com’

‘Connection’

‘keep-alive’

‘Content-Type’

“application/x-www-form-urlencoded; charset=UTF-8”

‘Referer’

‘http://music。163。com/’

“User-Agent”

“Mozilla/5。0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537。36”

“ (KHTML, like Gecko) Chrome/33。0。1750。152 Safari/537。36”

}

cookies

=

dict

appver

=

“1。2。1”

os

=

“osx”

res

=

None

if

method

==

“GET”

res

=

requests

get

action

headers

=

headers

cookies

=

cookies

timeout

=

timeout

elif

method

==

“POST”

res

=

requests

post

action

query

headers

=

self

headers

cookies

=

self

cookies

timeout

=

timeout

elif

method

==

“POST_UPDATE”

res

=

requests

post

action

query

headers

=

self

headers

cookies

=

self

cookies

timeout

=

timeout

self

cookies

update

res

cookies

get_dict

())

self

save_cookies

()

content

=

self

show_progress

res

content_str

=

content

decode

‘utf-8’

content_dict

=

json

loads

content_str

return

content_dict

def

user_playlist

self

uid

):

action

=

‘http://music。163。com/api/playlist/detail?id=’

+

str

uid

res_data

=

self

http_request

‘GET’

action

return

res_data

def

get_lyric_by_musicid

self

mid

):

url

=

‘http://music。163。com/api/song/lyric?’

+

‘id=’

+

str

mid

+

‘&lv=1&kv=1&tv=-1’

return

self

http_request

‘GET’

url

2。定義一個 Playlist 類:

class

Playlist

():

def

__init__

self

uid

):

self

id

=

uid

def

get

self

):

uid

=

self

id

import

re

music

=

NetEase

()

playlist

=

music

user_playlist

uid

=

uid

self

playlist

=

playlist

‘result’

][

‘tracks’

self

songName

=

[]

self

songId

=

[]

self

songImg

=

[]

self

songLrc

=

[]

for

song

in

self

playlist

self

songName

append

song

“name”

])

self

songId

append

song

“id”

])

self

songImg

append

song

“album”

][

“blurPicUrl”

])

for

songid

in

self

songId

lrc

=

music

get_lyric_by_musicid

mid

=

songid

lrc

=

lrc

‘lrc’

][

‘lyric’

pat

=

re

compile

r

‘\[。*\]’

lrc

=

re

sub

pat

“”

lrc

lrc

=

lrc

strip

()

self

songLrc

append

lrc

def

createImg

self

):

img

=

Img

()

for

songName

songLrc

songImg

in

zip

self

songName

self

songLrc

self

songImg

):

img

save

songName

songLrc

songImg

3。定義一個 Img 類來操作圖片:

class

Img

():

def

__init__

self

):

import

os

try

self

Path

=

r

‘C:\Img’

self

albumImgPath

=

self

Path

+

r

‘\albumImg’

os

mkdir

self

Path

os

mkdir

self

albumImgPath

except

pass

return

def

getsize

self

lrc

):

lrc

=

lrc

split

\n

width

=

[]

for

line

in

lrc

width

append

len

line

))

width

=

max

width

self

fontSize

=

500

//

width

-

1

# 字型大小

fontSpace

=

10

# 每行間隔大小

length

=

len

lrc

*

self

fontSize

+

fontSpace

return

width

length

def

save

self

name

lrc

imgurl

):

from

io

import

BytesIO

import

requests

width

length

=

self

getsize

lrc

from

PIL

import

Image

ImageDraw

ImageFont

albumImgSize

=

500

#專輯縮圖大小

font

=

“MFShangHei_Noncommercial-Regular。otf”

fontSize

=

self

fontSize

#字型大小

fontSpace

=

10

#每行間隔大小

space

=

10

#留白

rImg

=

requests

get

imgurl

albumImg

=

Image

open

BytesIO

rImg

content

))

albumImg

save

self

albumImgPath

+

r

\\

+

name

+

‘。bmp’

font

=

ImageFont

truetype

font

fontSize

rSizeImg

=

albumImg

resize

((

albumImgSize

albumImgSize

),

resample

=

3

x

=

albumImgSize

y

=

albumImgSize

+

length

+

space

*

4

outImg

=

Image

new

mode

=

‘RGB’

size

=

x

y

),

color

=

255

255

255

))

draw

=

ImageDraw

Draw

outImg

outImg

paste

rSizeImg

,(

0

0

))

draw

text

((

space

*

2

albumImgSize

+

space

*

2

),

lrc

font

=

font

fill

=

0

0

0

),

spacing

=

fontSpace

align

=

‘left’

draw

text

((

space

*

2

y

-

80

),

‘——’

+

name

fill

=

0

0

0

),

font

=

font

align

=

‘left’

outImg

save

self

Path

+

r

\\

+

name

+

‘。bmp’

return

4。最後呼叫:

id

=

input

‘請輸入歌單ID:’

music

=

Playlist

id

music

get

()

music

createImg

()