This is the second day of my participation in the Novembermore Challenge.The final text challenge in 2021
One, foreword
There are many ways to share a blog, but the most common is to share links. Or edit a message, put a title link and so on. But this way is not intuitive, compared to the way of the image is more eye-catching. CSDN Mobile provides the ability to share images, but the content is fixed, so I thought of generating my own sharing images in Python. This article is just a technical share, so there is not much effort in the effect, the generated images are much uglier than the official ones, and need to be included.
Two, crawl information
To generate the blog analysis graph, we need to get some information first, such as the author’s name, avatar, the abstract of the article and so on. Learn these Python beauty tips and wait for your girlfriend to praise you. Open your browser, right click to check, and you’ll see the following image:
In the upper left box we can see the author’s head and name, and that’s what we need. Click on the red box on the right, then click on the desired content in the web page, such as ZackSock, so that the browser will automatically locate the TAB in the source section:
We can see that the label is a span and the class is set to name, so we can use BeautifulSoup to parse it.
pip install BeautifulSoup4
Copy the code
Then perform the crawl:
import requests
from bs4 import BeautifulSoup
# the address of the blog to generate the share image
url = 'https://blog.csdn.net/ZackSock/article/details/105833676'
# Browser header information
headers = {
'user-agent': 'the Mozilla / 5.0 (Windows NT 10.0; Win64; X64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
Send a request to get the source code of the web page
response = requests.get(self.url, headers=headers)
# Get BeautifulSoup object
bs = BeautifulSoup(response.text, 'html.parser')
# find span tag with class as name
name = bs.find('span', {'class':'name'})
Get the text inside the tag
name = name.text.strip()
Copy the code
So we’ve climbed out the name of the blogger. In this way we can also crawl the head, but the summary does not know how to crawl. In my unprofessional analysis, I found that the body of the article is in a div with the id of content_views. If the format of the article is more formal, the first paragraph of non-heading text is in the div with the first non-empty P tag. We can then parse the summary using the following code:
import requests
from bs4 import BeautifulSoup
# the address of the blog to generate the share image
url = 'https://blog.csdn.net/ZackSock/article/details/105833676'
# Browser header information
headers = {
'user-agent': 'the Mozilla / 5.0 (Windows NT 10.0; Win64; X64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
Send a request to get the source code of the web page
response = requests.get(self.url, headers=headers)
# Get BeautifulSoup object
bs = BeautifulSoup(response.text, 'html.parser')
Get the HTML for the body
content = bs.find('div', {'id':'content_views'})
Get p in the text
p_s = content.find_all('p')
# Print the first non-empty p in the body
for p in p_s:
ifp.text ! =' ':
print(p.text)
Copy the code
The algorithm to climb the head is also very simple, the code is as follows:
import requests
from bs4 import BeautifulSoup
# the address of the blog to generate the share image
url = 'https://blog.csdn.net/ZackSock/article/details/105833676'
# Browser header information
headers = {
'user-agent': 'the Mozilla / 5.0 (Windows NT 10.0; Win64; X64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
Send a request to get the source code of the web page
response = requests.get(self.url, headers=headers)
# Get BeautifulSoup object
bs = BeautifulSoup(response.text, 'html.parser')
# find the img tag that displays your avatar
head_img = bs.find('img', {'class': 'avatar_pic'})
with open('head.jpg'.'wb') as f:
# Save images
f.write(requests.get(head_img['src']).content)
Copy the code
But the image we’re climbing to is square, and we need to do a process.
3. Deal with what we need
First we need to generate a round head, which uses the Pillow module. The setup is as follows:
pip install pillow
Copy the code
The specific code is as follows:
from PIL import ImageDraw
from PIL import Image
# read the profile picture
im = Image.open('head.jpg').convert('RGBA')
# Create an image that is the same size as your avatar
bg = Image.new('RGBA', im.size, (230.230.230.255))
# Cut a transparent circle over the image you created
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()
# Combine the avatar with the created avatar to create a round image
im.paste(bg, (0.0), mask=a)
# save
im.convert('RGB').save('head.jpg')
Copy the code
In addition, we need to use a qrcode to enable others to jump to our blog, which requires the qrcode module:
pip install qrcode
Copy the code
To generate the QR code, we need to pass in the blog address in the add_data method:
import qrcode
qr = qrcode.QRCode(
version=5.# Size of the qr code. The value ranges from 1 to 40
box_size=10.# Number of pixels of the smallest square of qr code
error_correction=qrcode.constants.ERROR_CORRECT_H, # Error correction level of two-dimensional code
border=1 # Size of white border
)
qr.add_data('Blog address') # Set qr code data
img = qr.make_image() # Create a qr code image
img.save('qrcode.png')
Copy the code
Of interested readers can watch qrcode module: https://blog.csdn.net/ZackSock/article/details/105222763.
4. Generate sharing graph
Now that we’ve finished our preparations, we can start our integration. You can get some of the information you need in the early stage and then integrate it according to your own layout. Here I am in the order of head picture, name, abstract and TWO-DIMENSIONAL code from top to bottom:
import re
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
bg_im = Image.new('RGB', (350.600), (230.230.230))
# Place the avatar
head_im = Image.open('head.jpg')
bg_im.paste(head_im, (140.70))
# place the name
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))
# Place summary
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
# Place qr code
qrcode = Image.open('qrcode.png')
qrcode = qrcode.resize((100.100))
bg_im.paste(qrcode, ((bg_im.size[0] -100) / /2.220+line*16+30))
# save
bg_im.save('results.jpg')
Copy the code
Since the abstract is quite long, I split the abstract into substrings of length 20 and then wrote it onto the image.
Four, integrating
We will integrate the above functions into a class, the complete code is as follows:
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) :
# Browser header information
headers = {
'user-agent': 'the Mozilla / 5.0 (Windows NT 10.0; Win64; X64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
# send request
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)
# Convert your avatar to a round box
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) :
Get the HTML for the body
content = bs.find('div', {'id':'content_views'})
Get p in the text
p_s = content.find_all('p')
# Print the first non-empty p in the body
for p in p_s:
ifp.text ! =' ':
return p.text
def get_qrcode(self) :
qr = qrcode.QRCode(
version=5.# Size of the qr code. The value ranges from 1 to 40
box_size=10.# Number of pixels of the smallest square of qr code
error_correction=qrcode.constants.ERROR_CORRECT_H, # Error correction level of two-dimensional code
border=1 # Size of white border
)
qr.add_data(self.url) # Set qr code data
img = qr.make_image() # Create a qr code image
img.save('qrcode.png')
def generate(self, name, abstract) :
bg_im = Image.new('RGB', self.size, (230.230.230))
# Place the avatar
head_im = Image.open('head.jpg')
bg_im.paste(head_im, (140.70))
# place the name
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))
# Place summary
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'
Create a generator object
generator = SharedGenerator(url)
# Get BeautifulSoup object
bs = generator.get_bs()
# Download and process the avatar
generator.get_img(bs)
Get the name
name = generator.get_name(bs)
# get summary
abstract = generator.get_abstract(bs)
# Generate qr code
generator.get_qrcode()
# Create a share image
generator.generate(name, abstract)
Copy the code
The above is a complete realization of the realization of the sharing diagram, the following is the effect diagram:
I replaced the original QR code with the beautiful woman in the picture. I’m not an artist, you can use your imagination to customize a more beautiful image to share.