近期疲于论文和别人给我挖的坑,可能很长一段时间不会更新博客了。

之前在寻找模板时发现了挺好的网站http://sc.chinaz/,上面有PPT,CSS,Bootstrap等许多种类的模板,并且有很多是可以免费获取。虽然免费的模板质量并不是很高,但是架不住数量多,仔细挑挑还是可以找到合适的模板的。

一个个下载自然是很麻烦的了,当然是选择搞个小爬虫,挂一个晚上就完事咯。

以PPT模板下载为例,思路非常简单

  1. 找到免费PPT陈列页面 http://sc.chinaz/ppt/free.html;
  2. 找到每个页面上20个PPT的超链接(利用正则去匹配合适的a链接);
  3. 进入超链接进入指定PPT页面后找到下载超链接;
  4. 访问下载超链接, 获取response.content, 以"wb"模式写入文件即可;

注意爬虫可能被封,所以代码中考虑了爬虫被封的重置。代码也非常简短,不足100行,注释很明确,就不加以赘述了👇

# -*- coding: UTF-8 -*-
# 作者:囚生CY
# 平台:CSDN
# 时间:2019/12/13
# 转载请注明原作者
# 创作不易,仅供分享

import os
import re
import time
import random
import requests
from bs4 import BeautifulSoup

host = "http://sc.chinaz"
firefoxHead = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0"}
htmlEncoding = "ISO-8859-1"

def get_PPT_page_free(session):											 # 获取免费PPT模板的总页数
	pptMainURL = host + "/ppt/free.html"								 # 免费PPT模板
	html = session.get(pptMainURL).text
	soup = BeautifulSoup(html,"lxml")
	bLabel = soup.find_all("b")
	return int(bLabel[-1].string)										 # 观察发现最后一个<b>标签内记录了总页码

def get_PPT_url_free(session,page):										 # 获取每个页面上所有PPT模板的超链接指向的URL
	regular = r"ppt/\d{9,12}"											 # PPT超链接的简约正则(当然可以更加简约,但是我认为这种写法最不容易出错)
	remain = "http://sc.chinaz/{}.htm"								 # 刨除简约正则部分剩下的部分
	pptMainURL = host + "/ppt/free.html"
	pptFreeURL = host + "/ppt/free_{}.html"
	url = pptMainURL if page==1 else pptFreeURL.format(page)			 # 第一页的URL与其他页码的有所不同		
	hrefs = []															 # 用于存储所有的链接
	html = session.get(url).text
	soup = BeautifulSoup(html,"lxml")
	aLabel = soup.find_all("a")											 # 所有的PPT超链接包含在<a>标签中
	for a in aLabel:
		try:
			href = a.attrs["href"]										 # 事实上有一些<a>标签是没有href属性的(由Java类生成重定向)
			result = re.findall(regular,href)[0]
			if result not in hrefs:	hrefs.append(result)				 # 事实上会产生重复的URL
		except: continue
	for i in range(len(hrefs)):	hrefs[i] = remain.format(hrefs[i])		 # 将简约正则补充为标准正则(即超链接指向的URL)
	return hrefs

def get_PPT_downloaded_free(session,pptURL,count,path="PPT\\{}"):		 # 下载PPT模板(给定PPT模板的URL)
	resetTime = 300														 # 倘若被封设定的重置时间
	html = session.get(pptURL).text
	soup = BeautifulSoup(html,"lxml")
	h1 = soup.find_all("h1")											 # h1标签中有PPT的名称
	name = str(h1[0].string).encode(htmlEncoding).decode("UTF-8")		 # 获取PPT模板名称(方便命名)
	print("正在获取第{}个PPT模板:\t{}\t".format(count,name))
	aLabel = soup.find_all("a")
	downloadURLs = []													 # 用于储存所有可用的下载链接
	for i in range(len(aLabel)):										 # 循环寻找第一个标签内容为"福建电信下载"的<a>标签的索引(另一种方法是第一个标签超链接以.rar结尾的索引)
		string = str(aLabel[i].string).encode(htmlEncoding).decode("UTF-8") # 编解码处理乱码
		if "福建电信下载" == string: index = i												 
	for i in range(index,index+12):	downloadURLs.append(aLabel[i].attrs["href"]) # 一般来说接下来连续的12个都是下载地址
	while True:															 # 考虑到可能下载失败, 所以使用循环去多试试几个URL
		try:
			downloadURLs = downloadURLs[random.randint(0,11)]			 # 考虑在12个下载地址中随机选择一个
			content = session.get(downloadURLs).content
			rar = open(path.format("{}_{}.rar".format(count,name)),"wb")
			rar.write(content)
			rar.close()
			break
		except:
			print("-----------------访问过于频繁,正在重置连接--------------------")
			total = 0
			while total<resetTime:
				print("还剩{}秒".format(resetTime-total))
				time.sleep(1)
				total += 1
			continue

def get_PPT_models_free(session):										 # 实现大规模PPT模板下载
	pptMainURL = host + "/ppt/free.html"
	page = get_PPT_page_free(session)									 # 总页数
	count = 0															 # 计数
	for i in range(page):												 # 一页页来吧
		print("正在获取第{}页的PPT模板".format(i+1))
		pptURLs = get_PPT_url_free(session,i+1)
		for pptURL in pptURLs:
			count += 1
			get_PPT_downloaded_free(session,pptURL,count)
			time.sleep(random.randint(5,10))

def main():
	session = requests.Session()
	session.headers = firefoxHead
	session.get(host)
	get_PPT_models_free(session)

if __name__ == "__main__":
	if not os.path.exists("PPT"): os.mkdir("{}\\PPT".format(os.getcwd()))  # 新建文件夹
	main()

 

最后简单展示一下一晚上的成果。

PPT模板下载情况👇

 

 HTML模板下载情况👇

HTML的就不展示了,跟PPT的也差不多,自己写写吧。

分享学习,共同进步!

 

更多推荐

【日常】python站长素材网免费模板下载(以PPT模板为例)