拿著爬蟲資料,搞事情啊!!

無聊小碼農發表於2018-08-03

背景

接上篇使用Puppeteer輕鬆爬取網易雲音樂、QQ音樂的精品歌單,沒有看的可以看看,順便給個小心心啊!

上一篇我們通過Puppeteer爬取了,網易雲音樂和QQ音樂播放量超過1000W的歌單,為了更好的獲取和分享歌單,這次我們通過程式碼合成能夠分享的圖片。

本次採用語言為:Python,NodeJS版本正在開發中,後續會分享出來。

程式碼地址

專案完整程式碼地址:圖片合成

工具

  • python2.7:python 版本 2.7,其他版本也可,不過依賴庫安裝要作出相應修改
  • PIL:圖片處理庫,詳細瞭解請移步文件
  • pathlib:目錄地址庫,主要處理檔案的目錄關係
  • requests:請求庫,主要用來請求網路資源
  • qrcode:二維碼生成庫,主要用來生成二維碼
  • 字型檔案:自行下載可用的字型檔案ttf

效果

先上兩張效果圖,來看一下。

網易雲音樂歌單

QQ歌單

思路

先分析一下圖片的主要點:

  • 需要一張背景圖
  • 需要一個資料來源,提供生成分享圖的資料
  • 計算圖片和文字的地址,生成文字
  • 生成相應類別的二維碼
  • 貼上二維碼到背景的相應位置

準備工作

python環境

安裝 python 執行環境,可以是 2.7 或者 3.* 版本,根據自己需要安裝。

具體安裝方法參考官網

具體的每個系統相關的安裝教程,請自行百度,這裡不再贅述。

安裝PIL庫

安裝用來處理圖片的庫 PIL。

具體安裝方法和不同系統以及 python 版本的相應安裝命令,參閱官網

安裝pathlib

安裝路徑相關的依賴庫。

pip install pathlib
複製程式碼

安裝requests

pip install requests
複製程式碼

安裝qrcode

pip install qrcode
複製程式碼

下載依賴字型檔案

字型檔案為可選項,可以下載自己喜愛的字型,實現自定義字型,也可以使用預設字型。

開工

首先分析一下我們要幹些什麼。

  • 找一張背景圖
  • 在圖片上新增文字
  • 在圖片上新增圖片
  • 生成二維碼圖片
  • 把二維碼貼到圖片上

找一張合適的背景圖

Unsplash 上找一張適合做背景的圖片。

背景圖

調整到合適的尺寸。

新增文字

通過 PIL 的方法,想圖片上繪製文字。

def add_text(img, text, size, position, color="#9400D3"):
    draw = ImageDraw.Draw(img)
    # 設定字型為自定義字型
    font = ImageFont.truetype('MFJingYue.ttf', size)
    draw.text(position, text, fill=color, font=font, align="center")
複製程式碼

新增文字需要給定新增的位置,所以我們還需要一個方法來確定文字的位置。

# 獲取文字的x座標,主要用來設定歌單名稱的位置,保證每行居中並不會太長
def get_x_position(len):
    max = 14
    x = 50 + (max - len) * 25 / 2
    return x
複製程式碼

番外話:為了簡單,我直接在這裡設定的字號為50,寫死了,如果想要自定義的換可以多加一個引數,然後根據需求設定具體的位置

新增圖片

通過 PIL 的方法可以直接把一張圖片貼上到另一張圖片上。

# 下邊為例子
img_one = Image.open(pathlib.Path('one.jpg'));
img_two = Image.open(pathlib.Path('two.jpg'));
# 設定圖片替換位置
box = (100, 50, 350, 300)
# 選取圖片,並設定大小
region = img_one
region = region.resize((box[2] - box[0], box[3] - box[1]))
# 貼上圖片到相應位置
img_two.paste(region, box)
複製程式碼

生成二維碼

通過 qrcode 庫,我們能夠很容易的生成二維碼,然後根據我們資料的來源打上相應的 logo。

# 生成二維碼
def make_qrcode(url, type):
    qr = qrcode.QRCode(
        version=5,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=8,
        border=3
    )
    qr.add_data(url)
    # qr.make(fit = True)
    img = qr.make_image()
    img = img.convert("RGBA")
    icon = None
    if type == 'netease':
        icon = Image.open(pathlib.Path('netease.png'))
    elif type == 'qq':
        icon = Image.open(pathlib.Path('qq.png'))
    img_w, img_h = img.size
    factor = 4
    size_w = int(img_w/factor)
    size_h = int(img_h/factor)
    
    icon_w, icon_h = icon.size
    if icon_w > size_w:
        icon_w = size_w
    if icon_h > size_h:
        icon_h = size_h
    icon = icon.resize((icon_w, icon_h), Image.ANTIALIAS)
    
    w = int((img_w-icon_w)/2)
    h = int((img_h-icon_h)/2)
    img.paste(icon, (w,h), icon)
    # 最後返回圖片物件
    return img
複製程式碼

貼上二維碼

生成的二維碼為一個圖片物件,我們可以直接通過圖片的貼上方法,直接貼上到相應的位置。

# 生成二維碼地址
qrcode_img = make_qrcode(address, type)
# 貼上到背景圖上
box_qrcode = (300, 527, 425, 652)
print qrcode_img.size, qrcode_img.mode
# qrcode_img.save('./qrcode.png')
region_qrcode = qrcode_img
region_qrcode = region_qrcode.resize((box_qrcode[2] - box_qrcode[0], box_qrcode[3] - box_qrcode[1]))
background_img.paste(region_qrcode, box_qrcode)
複製程式碼

整理程式碼

最後把所有的功能整合成一個方法,然後通過引數,傳入相對應的引數,就能生成一張能夠用於分享的圖片了。

# 合成分享圖
def merge_img(img_src, name, count, address, author, type):
    save_name = './' + name + '.jpg'
    name = unicode(name, 'UTF-8')
    count = unicode("播放量:" + count, 'UTF-8')
    author = unicode("建立人:" + author, 'UTF-8')
    background_img = Image.open(pathlib.Path('background.jpg'))
    # 獲取遠端圖片
    response = requests.get(img_src)
    img = Image.open(BytesIO(response.content))
    # 設定圖片替換位置
    box = (100, 50, 350, 300)
    # 選取圖片
    region = img
    region = region.resize((box[2] - box[0], box[3] - box[1]))
    # 貼上到背景圖上
    background_img.paste(region, box)
    # 新增名字
    name_len = len(name)
    if name_len <= 14:
        x = get_x_position(name_len)
        add_text(background_img, name, 25, (x, 330))
    else:
        name_one = name[0:14]
        print name_one
        add_text(background_img, name_one, 25, (50, 330))
        name_two = name[14:name_len]
        print name_two
        x = get_x_position(len(name_two))
        add_text(background_img, name_two, 25, (x, 370))
    # 新增建立者
    add_text(background_img, author, 20, (50, 560), color='white')
    # 新增播放數
    add_text(background_img, count, 20, (50, 600), color='white')
    # 生成二維碼地址
    qrcode_img = make_qrcode(address, type)
    # 貼上到背景圖上
    box_qrcode = (300, 527, 425, 652)
    print qrcode_img.size, qrcode_img.mode
    # qrcode_img.save('./qrcode.png')
    region_qrcode = qrcode_img
    region_qrcode = region_qrcode.resize((box_qrcode[2] - box_qrcode[0], box_qrcode[3] - box_qrcode[1]))
    background_img.paste(region_qrcode, box_qrcode)
    # 儲存圖片
    background_img.save(save_name)
複製程式碼

測試

img_one = 'https://p.qpic.cn/music_cover/1Fr9IFMhWDPeUzWKVEjn3VLzce1PenAOaaImqzoibx2iaE5rhV0RwMYA/300?n=1'
img_two = 'http://p1.music.126.net/wpahk9cQCDtdzJPE52EzJQ==/109951163271025942.jpg?param=140y140'
address_one = 'https://y.qq.com/n/yqq/playsquare/2643652402.html#stat=y_new.playlist.pic_click'
address_two = 'https://music.163.com/#/playlist?id=2201879658'
name_one = '回頭率最高的50首手機鈴聲'
name_two = '你的青春裡有沒有屬於你的一首歌?'
merge_img(img_one, name_one, '4622.8萬', address_one, author="Harry", type="qq")
merge_img(img_two, name_two, '2428萬', address_two, author="mayuko然", type="netease")
複製程式碼

然後就生成了,開始我們看到的兩張圖片了。

總結

對於圖片的處理 PIL 十分強大,擁有很多方法可供使用,是一個不錯的庫。

通過簡單的學習,能夠根據思路生成不同的分享圖片,對於有強烈分享需求的介面來說是個不錯的嘗試。

相關文章