菜狗大学生一枚,本着用什么学什么的原则,对之前简单学习的爬虫进行略微系统的整理,一方面方便以后复习,另一方面也希望给需要的人一点参考,毕竟看了那么多大佬的博客,是时候开始回报社会了哈哈哈(尴尬笑)。
本人对Python的了解不是很多,只是因为某个小项目的需求所以学习了一下,而且我很菜的(大实话),因此如果下文有误,还望各位批评指正。本文的简易爬虫参考了某位大佬的博客,大佬的文章思路清晰,写的也简洁易懂,可惜因为是好几个月之前看的了,实在找不到大佬的文章,此处表示万分感谢。
说回正题,本文主要实现对第1PPT网站(不知道这里要不要打码=_=,侵删)中PPT模板的爬取,属于爬虫中较为简单基础的类型,适合同为小白的同学观看(巨佬请绕路)。
1.对爬虫的简单理解:利用编写代码实现机械化的从网页源代码中将我们想要的东西提取出来的方法,这些东西可以是一些特定的文字,也可以是一个个可下载的资源。本文主要讨论后者。
对于可下载资源,我们只需要找到藏在网页源代码中的资源链接(URL)即可。通常,一个界面只会存在一个资源的模板。例如,唯美PPT模板分类下有1到10共10个不同的PPT,点击相应的PPT会进入详情界面,该PPT的下载链接就在其中,代码要做的无非是对这10个界面进行遍历,依次找出模板资源的URL。
2.网页源代码怎么看:这个问题很简单啦,大多数浏览器都可以查看网页源代码,也不用我们对HTML的了解有多深。以第1PPT网站为例,模板详情界面就有下载按钮,在源代码里该按钮的链接就是资源文件的URL。如下图。
3.正则表达式:一个超级有用的东西(虽然内容太多我到现在也没有懂得很多),通常同一个网站的同类型网页的布局、代码都是类似的或相同的,通过正则表达式我们可以精确的匹配到网页源代码中我们想要的内容。就像上面这张图片,我们可以看到链接在
第一PPT素材下载(网通电信双线)
因此我们匹配
4.requests和futures模块:这个其实没啥好说的,前者用于网络请求,后者用于线程池。需要注意的是使用futures模块的线程池时,模块内部会调用logging,如果不作配置的话可能会报错。
No handlers could be found for logger "concurrent.futures"
解决方法:
import logging
logging.basicConfig()
我觉得这里可能就是给logging做了一个初始化的工作,没细研究2333,有兴趣的小伙伴可以去仔细研究下。
下面开始贴代码。
import re
import requests
import hashlib
import time
import os
import logging
from concurrent.futures import ThreadPoolExecutor
#初始化logging
logging.basicConfig()
# 定义线程池最多容纳30个线程
p = ThreadPoolExecutor(30)
# 链接到第一ppt免费ppt模板的界面
def get_Index(url):
respose = requests.get(url)
#响应状态码为200代表请求成功
if respose.status_code == 200:
print("网站链接成功")
return respose.text
else:
print("无法链接到模板界面")
return
# 解析获取到的html代码,获取当前页面每个ppt模板的链接
def parse_Index(res):
res = res.result()
# 正则表达式获取模板链接
urls = re.findall(r'h2.*?href="(.*?)"', res, re.S)
for url in urls:
# 提交到线程池
p.submit(get_Detail(url))
# 模板详情界面
def get_Detail(url):
if not url.startswith('http'):
url = 'http://www.1ppt.com%s' % url
detailRespose = requests.get(url)
#成功获取
if detailRespose.status_code == 200:
ppt_url = re.findall(r'class="downurllist".*?href="(.*?)"', detailRespose.text, re.S)
#避免单线程获取多个url
ppt_url = ppt_url[0]
if ppt_url:
print(ppt_url)
save(ppt_url)
else:
print("无法连接的详情界面")
return
# 将文件保存
def save(ppt_url):
ppt = requests.get(ppt_url)
if ppt.status_code == 200:
#利用md5值作为文件名
m = hashlib.md5()
m.update(ppt_url.encode('utf-8'))
m.update(str(time.time()).encode('utf-8'))
#文件保存路径与文件写入
directorypath='E:\\ppt'
filepath = r'E:\\ppt\\%s.zip' % m.hexdigest()
if not os.path.exists(directorypath):
os.makedirs(directorypath)
with open(filepath, 'wb') as f:
f.write(ppt.content)
else:
print("无法下载")
return
def main():
#以PPT模板第5-7页为例
for i in range(5, 7):
p.submit(get_Index, 'http://www.1ppt.com/moban/ppt_moban_%s.html' % i).add_done_callback(parse_Index)
if __name__ == '__main__':
main()
以上是一个简单爬虫的编写过程,不当之处望请指正。下一篇将继续介绍稍微复杂一点的、资源URL并非直接放在源代码中的网页资源爬取代码的编写。