Python生成CSDN博客分享圖

Python生成CSDN博客分享圖

一、前言

我們分享博客的方式有很多種,最常見的無非就是分享鏈接。或者是編輯一條消息,寫上標題鏈接等東西。但是這種方式都不夠直觀,相比之下圖片的方式要更引人注目。CSDN移動端提供了分享圖的功能,但是展示的內容是固定的,所以我就想到用Python自己生成分享圖。本文只是技術分享,所以在效果上沒有下太多功夫,生成的圖片比官方是要醜得多,還需包含。

二、爬取信息

我們要生成博客分析圖,就需要先獲得一些信息,像是作者的名字,頭像,文章的摘要等。這就需要使用到爬蟲了,先選取本人的一篇博客:學會這些Python美圖技巧,就等着女朋友誇你吧,我們在瀏覽器打開,右擊檢查就可以看到下圖:

在這裏插入圖片描述

在左上角的框我們可以看到作者的頭像和名字,那就是我們需要的內容。我們先點擊右邊紅框,然後在網頁中點擊我們需要的內容,比如ZackSock,這樣瀏覽器在源碼部分會自動定位到該標籤:

在這裏插入圖片描述

我們可以看到該標籤是一個span,而且class設置爲name,這個時候我們就可以用BeautifulSoup解析,安裝語句如下:

pip install BeautifulSoup4

然後進行爬取:

import requests
from bs4 import BeautifulSoup
# 要生成分享圖的博客地址
url = 'https://blog.csdn.net/ZackSock/article/details/105833676'
# 瀏覽器頭信息
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
# 發送請求,獲取網頁源碼
response = requests.get(self.url, headers=headers)
# 獲取BeautifulSoup對象
bs = BeautifulSoup(response.text, 'html.parser')
# 找到源碼中class爲name的span標籤
name = bs.find('span', {'class':'name'})
# 獲取標籤裏面的文字
name = name.text.strip()

這樣我們就將博主的名字爬了出來。通過這個方法我們還可以爬取頭像,但是摘要就不知道怎麼爬了。進行我的不專業分析,發現文章的主體都在一個idcontent_viewsdiv中,如果文章格式比較規範的話,第一段非標題文字就在div中第一個非空p標籤中。於是我們就可以用下面代碼分析出摘要:

import requests
from bs4 import BeautifulSoup
# 要生成分享圖的博客地址
url = 'https://blog.csdn.net/ZackSock/article/details/105833676'
# 瀏覽器頭信息
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
# 發送請求,獲取網頁源碼
response = requests.get(self.url, headers=headers)
# 獲取BeautifulSoup對象
bs = BeautifulSoup(response.text, 'html.parser') 
# 獲取正文的html
content = bs.find('div', {'id':'content_views'})
# 獲取正文中的p
p_s = content.find_all('p')
# 將正文第一個非空p輸出
for p in p_s:
	if p.text != '':
		print(p.text)

爬取頭像的算法也非常簡單,代碼如下:

import requests
from bs4 import BeautifulSoup
# 要生成分享圖的博客地址
url = 'https://blog.csdn.net/ZackSock/article/details/105833676'
# 瀏覽器頭信息
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
# 發送請求,獲取網頁源碼
response = requests.get(self.url, headers=headers)
# 獲取BeautifulSoup對象
bs = BeautifulSoup(response.text, 'html.parser') 
# 找到顯示頭像的img標籤
head_img = bs.find('img', {'class': 'avatar_pic'})
with open('head.jpg', 'wb') as f:
    # 保存圖片
	f.write(requests.get(head_img['src']).content)

但是我們爬到的圖片是正方形的,我們需要進行一個處理。

三、處理我們需要的內容

首先我們需要生成一個圓形的頭像,這就需要用到Pillow模塊,安裝如下:

pip install pillow

具體代碼如下:

from PIL import ImageDraw
from PIL import Image
# 讀取頭像圖片
im = Image.open('head.jpg').convert('RGBA')
# 創建一個和頭像大小一樣的圖片
bg = Image.new('RGBA', im.size, (230, 230, 230, 255))
# 在創建的圖片上摳一個透明圓形
drawer = ImageDraw.Draw(bg)
drawer.ellipse((0, 0, bg.size[0], bg.size[0]), fill=(0, 0, 0, 0), width=3)

r, g, b, a = bg.split()
# 將頭像和創建的頭像合併,就合成了一個圓形圖片
im.paste(bg, (0, 0), mask=a)
# 保存
im.convert('RGB').save('head.jpg')

另外,我們需要用一個二維碼讓別人可以跳轉到我們的博客,這需要用到qrcode模塊:

pip install qrcode

生成二維碼的代碼如下,我們需要在add_data方法中傳入博客地址:

import qrcode
qr = qrcode.QRCode(
	version=5,  # 二維碼的大小,取值1-40
    box_size=10,  # 二維碼最小正方形的像素數量
    error_correction=qrcode.constants.ERROR_CORRECT_H,  # 二維碼的糾錯等級
    border=1  # 白色邊框的大小
)
qr.add_data('博客地址')  # 設置二維碼數據
img = qr.make_image()  # 創建二維碼圖片
img.save('qrcode.png')

對qrcode模塊有興趣的讀者可以觀看: https://blog.csdn.net/ZackSock/article/details/105222763

四、生成分享圖

上面我們把準備工作做完了,可以開始我們的整合了。大家前期可以獲取一些自己需要的信息然後按照自己的佈局整合,這裏我就是按照從上到下依次頭像、名稱、摘要、二維碼的排序:

import re
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw

bg_im = Image.new('RGB', (350, 600), (230, 230, 230))
# 放置頭像
head_im = Image.open('head.jpg')
bg_im.paste(head_im, (140, 70))
        
# 放置名字
drawer = ImageDraw.Draw(bg_im)
font = ImageFont.truetype('simsun.ttc', 14)
w, h = drawer.textsize(name)
drawer.text(((bg_im.size[0]-w)/2, 160), name, font=font, fill=(15, 15, 15))

# 放置摘要
st = re.findall(r'.{20}', abstract)
line = 0
for i in st:
	w, h = drawer.textsize(i.encode('utf-8'))
	drawer.text(((bg_im.size[0]-w)/2-20, 220+line*16), i, font=font, fill=(15, 15, 15))
	line += 1
    
# 放置二維碼
qrcode = Image.open('qrcode.png')
qrcode = qrcode.resize((100, 100))
bg_im.paste(qrcode, ((bg_im.size[0]-100)//2, 220+line*16+30))

# 保存
bg_im.save('results.jpg')

因爲摘要比較長,所以我把摘要分成了數個長度爲20的子串然後再寫到圖片上。

四、整合

我們將上面的函數整合一個類,完整代碼如下:

import re
import qrcode
import requests
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
from bs4 import BeautifulSoup


class SharedGenerator():

    def __init__(self, url):
        self.size = (350, 600)
        self.url = url

    def get_bs(self):
        # 瀏覽器頭信息
        headers = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
        }
        # 發送請求
        response = requests.get(self.url, headers=headers)
        bs = BeautifulSoup(response.text, 'html.parser')

        return bs

    def get_img(self, bs):

        head_img = bs.find('img', {'class': 'avatar_pic'})

        with open('head.jpg', 'wb') as f:
            f.write(requests.get(head_img['src']).content)

        # 將頭像轉換成圓框
        im = Image.open('head.jpg').convert('RGBA')
        bg = Image.new('RGBA', im.size, (230, 230, 230, 255))

        drawer = ImageDraw.Draw(bg)
        drawer.ellipse((0, 0, bg.size[0], bg.size[0]), fill=(0, 0, 0, 0), width=3)

        r, g, b, a = bg.split()

        im.paste(bg, (0, 0), mask=a)

        im.convert('RGB').save('head.jpg')


    def get_name(self, bs):
        name = bs.find('span', {'class':'name'})
        return name.text.strip()

    def get_abstract(self, bs):
        # 獲取正文的html
        content = bs.find('div', {'id':'content_views'})
        # 獲取正文中的p
        p_s = content.find_all('p')
        # 將正文第一個非空p輸出
        for p in p_s:
            if p.text != '':
                return p.text

    def get_qrcode(self):
        qr = qrcode.QRCode(
            version=5,  # 二維碼的大小,取值1-40
            box_size=10,  # 二維碼最小正方形的像素數量
            error_correction=qrcode.constants.ERROR_CORRECT_H,  # 二維碼的糾錯等級
            border=1  # 白色邊框的大小
        )
        qr.add_data(self.url)  # 設置二維碼數據
        img = qr.make_image()  # 創建二維碼圖片
        img.save('qrcode.png')


    def generate(self, name, abstract):
        bg_im = Image.new('RGB', self.size, (230, 230, 230))
        # 放置頭像
        head_im = Image.open('head.jpg')
        bg_im.paste(head_im, (140, 70))
        # 放置名字
        drawer = ImageDraw.Draw(bg_im)
        font = ImageFont.truetype('simsun.ttc', 14)
        w, h = drawer.textsize(name)
        drawer.text(((bg_im.size[0]-w)/2, 160), name, font=font, fill=(15, 15, 15))
        # 放置摘要
        st = re.findall(r'.{20}', abstract)
        line = 0
        for i in st:
            w, h = drawer.textsize(i.encode('utf-8'))
            drawer.text(((bg_im.size[0]-w)/2-20, 220+line*16), i, font=font, fill=(15, 15, 15))
            line += 1

        qrcode = Image.open('qrcode.png')
        qrcode = qrcode.resize((100, 100))

        bg_im.paste(qrcode, ((bg_im.size[0]-100)//2, 220+line*16+30))

        bg_im.save('results.jpg')

if __name__ == '__main__':
    url = 'https://blog.csdn.net/ZackSock/article/details/105833676'
    # 創建生成器對象
    generator = SharedGenerator(url)
    # 獲取BeautifulSoup對象
    bs = generator.get_bs()
    # 下載並處理頭像
    generator.get_img(bs)
    # 獲取名字
    name = generator.get_name(bs)
    # 獲取摘要
    abstract = generator.get_abstract(bs)
    # 生成二維碼
    generator.get_qrcode()
    # 生成分享圖
    generator.generate(name, abstract)

上面就完整的實現了分享圖的實現,下面是效果圖:

在這裏插入圖片描述

我把原本的二維碼替換成了圖中的美女。我沒有什麼藝術細胞,大家可以發揮自己的想象定製一個更美觀的分享圖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章