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()
這樣我們就將博主的名字爬了出來。通過這個方法我們還可以爬取頭像,但是摘要就不知道怎麼爬了。進行我的不專業分析,發現文章的主體都在一個id
爲content_views
的div
中,如果文章格式比較規範的話,第一段非標題文字就在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)
上面就完整的實現了分享圖的實現,下面是效果圖:
我把原本的二維碼替換成了圖中的美女。我沒有什麼藝術細胞,大家可以發揮自己的想象定製一個更美觀的分享圖。