爬取全国大学校徽合集批量制作队牌

目标

下载收集中国全国范围内各大高校的校徽,并批量制作比赛名牌。

背景

我们学校承办了ICPC济南站,给我分配的任务是给每家学校做一个类似于下图的带校徽的海报。

其中中间的校徽要替换成别的学校的。参赛名单上有两三百个学校,挨个手工下载校徽再手工合成不如直接找印务公司。所以开始思考这个任务可以分解成两步:

  • 根据队伍名单批量收集所需大学的校徽
  • 将校徽批量嵌入到海报中去

批量收集校徽

第一想法是找找有没有现成的API,搜了一圈后无果。

第二想法是找个有资源的网站批量爬取。又想到很多学校举办大型竞赛的时候都应该遇到这个问题,应该有与我同样想法的程序员干过同样的事儿。遂直接到github上搜索。运气很好的看到了下面这个项目:

dashjay/UniversityBadge: 中国大部分大学校徽,来自百度百科

不过拿这个项目直接爬下来的校徽太小了,我稍微改了改代码让下载下来的校徽变得高清了一点

# -*- coding: UTF-8 -*-
import os
import json
import requests
import re
from bs4 import BeautifulSoup
from urllib import request

# ---------------获取大学信息,将对应大学url储存在Urllist中-----------------------------------

Urllist = []
f = open("university_name.csv", "r")
line = f.readline()
while line:
    Urllist.append("https://baike.baidu.com/item/"+line.strip())
    line = f.readline()

# ---------------------------------------------------------------------------------------
# ---------------------Badge Spider------------------------------------------------------
# 无法直接请求的url = 41

heads = [{'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'},
         {'User-Agent': 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 Safari/535.11'},
         {'User-Agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)'}]
UCurl = []

# img格式选择函数


def getImgUrl(a=[], b=[]):
    if(a == []):
        return b
    else:
        return a

folder = os.path.exists("Badges")
if not folder:
    os.makedirs("Badges")
for url in Urllist:
    num = 0
    response = requests.get(url, allow_redirects=False,
                            headers=heads[num % len(heads)])
    # 判断请求的 url 是否有效
    if response.status_code == 200:
        response.encoding = ('utf-8')  # 将请求到的页面转码
        html = response.text  # 请求的 url 的 html 代码
        soup = BeautifulSoup(html, 'html.parser')  # 用html.parser对网页解析

        img2 = soup.select(
            'body > div.body-wrapper.feature.feature_small.collegeSmall > div.feature_poster > div > div.poster-right > div > a > img')
        # 选择校徽图片的位置,得到校徽块相关信息
        img1 = soup.select(
            'body > div.body-wrapper > div.content-wrapper > div > div.side-content > div.summary-pic > a > img')
        # 由于百度百科的 badge 图片的html格式有所不同,但基本为这两个格式,所以添加两个img格式

        img = getImgUrl(img1, img2)


        if img == []:
            with open('unfinishedURL.txt', 'a') as fo:
                fo.writelines(url)
                fo.writelines('\n')
            continue

        img_url = img[0].get_attribute_list('src')[0]  # 获取校徽图片地址
        img_url = re.match('https[\S]+process=image', img_url).group() # 去除修饰后缀,获取原始清晰度图片

        if img_url == None:
            # 理应永远执行不到这里
            print('error : ' + url)
            exit()

        # 将获得的校徽图片保存本地
        pic = requests.get(img_url)
        path = 'Badges/'+url[29:]+'.jpg'
        with open(path, 'wb') as fp:
            fp.write(pic.content)
    # url 地址请求失败时,将失败的URL存入 unfinishedURL 文本中
    else:
        with open('unfinishedURL.txt', 'a') as fo:
            fo.writelines(url)
            fo.writelines('\n')
    num = num + 1
    print(url)

print("OK!Well Done!")

下载下来的校徽还不能直接用,大概有5%的会有百度百科的水印。因为个数少,人工挨个改改就行。还有极少数图片带有非白色的边框,也得挨个改改。

批量合成图片

我拿到的图片是这样的空白图。主要思路就行把别的校徽按比例缩放到和右侧校徽同等高度后,居中放置。不按宽度缩放是因为部分学校的校徽是长方形的。

这部分工作主要借助PIL库实现,代码很简单。

import csv
from PIL import Image

with open('university_name.csv') as f:
	reader = csv.reader(f)
	for row in reader:
		base_img = Image.open('blank.jpg')
		tmp_img = Image.open('Badges\\' + str(row[0]) + '.jpg')
		tmp_img = tmp_img.convert("RGB")
		region = tmp_img
		# 标准情况下中间校徽的尺寸
		tbox = (1395,525, 2110,1245)
		# 计算缩放后的宽高
		height = tbox[3] - tbox[1]
		width = tmp_img.width*(height/tmp_img.height)
		mid = (tbox[0]+tbox[2])/2 # 中轴线
		box = (int(mid - width/2) , tbox[1], int(mid + width/2) , int(tbox[1]+height) )
		region = region.resize((box[2] - box[0], box[3] - box[1]))
		base_img.paste(region, box)
		base_img.save('out\\' + str(row[0]) + '.jpg')
		print(str(row[0]))

后记

比较悲催的是打印店告知我做的图太小了,作为1米多的海报打出来太糊了。所以我把标题从批量制作海报改成了批量制作队牌了。
再见,我去学怎样用PS了。

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值