一。任务用途:
老师让下载某个网页的所有图书的电子版。我看了一下图书很多,约有五六百本,下载后还需要手动改名,每种图书在不同的分类里,很麻烦,于是决定动手做一个爬虫程序来爬取图书,并修改名称保存pdf文档。
二。任务规划:
1.首先打开需要爬取的网页:https://bp.pep.com.cn/jc/,但是分8个种类,我们依次访问。
2.依次访问每个网页:并提取相应的书籍种类,每个种类的每本书籍(书籍名称,书籍链接,书籍保存的路径)。
3.写一个下载的函数:根据书籍的特征(书籍名称,书籍链接,书籍保存的路径)下载书籍并保存。
三。实践:
1.程序及工具:
Python(IDLE), 第三方库(requests, BeautifulSoup)
2.简单分析html页面及代码:
打开网页:https://bp.pep.com.cn/jc/ywjygjkcjc/,并查看源代码:(截取关键部分)
<div class="con_list_jcdzs2020">
<div class="con_title_jcdzs2020">
<h4>小学道德与法治教科书</h4>
</div>
<ul class="clearfix">
<li class="fl js_cp">
<a href="http://bp.pep.com.cn/ebook/ddyfzyinjxc/index.html" target="_blank" title="道德与法治一年级下册"><img src="./xdjc/202001/W020200211450096154325.jpg" width="158" height="220" alt="" /></a>
<h6><a href="http://bp.pep.com.cn/ebook/ddyfzyinjxc/index.html" target="_blank" title="道德与法治一年级下册">道德与法治一年级下册</a></h6>
<div class="con_type_link_jcdzs2020">
<a href="http://bp.pep.com.cn/ebook/ddyfzyinjxc/" target="_blank" title="阅读" class="btn_type_dy">阅读</a>
<a href="./xdjc/202001/P020200219781109508538.pdf" target="_blank" title="下载" class="btn_type_dl">下载</a>
</div>
<li class="fl js_cp">
<a href="http://bp.pep.com.cn/ebook/ddyfzernjxc/index.html" target="_blank" title="道德与法治二年级下册"><img src="./xdjc/202002/W020200211347248052630.jpg" width="158" height="220" alt="" /></a>
<h6><a href="http://bp.pep.com.cn/ebook/ddyfzernjxc/index.html" target="_blank" title="道德与法治二年级下册">道德与法治二年级下册</a></h6>
<div class="con_type_link_jcdzs2020">
<a href="http://bp.pep.com.cn/ebook/ddyfzernjxc/" target="_blank" title="阅读" class="btn_type_dy">阅读</a>
<a href="./xdjc/202002/P020200219781571803740.pdf" target="_blank" title="下载" class="btn_type_dl">下载</a>
</div>
<li class="fl js_cp">
<a href="http://bp.pep.com.cn/ebook/ddyfzsannjxc/index.html" target="_blank" title="道德与法治三年级下册"><img src="./xdjc/202002/W020200211347416043255.jpg" width="158" height="220" alt="" /></a>
<h6><a href="http://bp.pep.com.cn/ebook/ddyfzsannjxc/index.html" target="_blank" title="道德与法治三年级下册">道德与法治三年级下册</a></h6>
<div class="con_type_link_jcdzs2020">
<a href="http://bp.pep.com.cn/ebook/ddyfzsannjxc/" target="_blank" title="阅读" class="btn_type_dy">阅读</a>
<a href="./xdjc/202002/P020200219781875628182.pdf" target="_blank" title="下载" class="btn_type_dl">下载</a>
</div>
<li class="fl js_cp">
<a href="http://bp.pep.com.cn/ebook/ddyfzsinjxc/index.html" target="_blank" title="道德与法治四年级下册"><img src="./xdjc/202002/W020200211347618578841.jpg" width="158" height="220" alt="" /></a>
<h6><a href="http://bp.pep.com.cn/ebook/ddyfzsinjxc/index.html" target="_blank" title="道德与法治四年级下册">道德与法治四年级下册</a></h6>
<div class="con_type_link_jcdzs2020">
<a href="http://bp.pep.com.cn/ebook/ddyfzsinjxc/" target="_blank" title="阅读" class="btn_type_dy">阅读</a>
<a href="./xdjc/202002/P020200210134530437869.pdf" target="_blank" title="下载" class="btn_type_dl">下载</a>
</div>
<li class="fl js_cp">
<a href="http://bp.pep.com.cn/ebook/ddyfzwunjxc/index.html" target="_blank" title="道德与法治五年级下册"><img src="./xdjc/202002/W020200211347778557647.jpg" width="158" height="220" alt="" /></a>
<h6><a href="http://bp.pep.com.cn/ebook/ddyfzwunjxc/index.html" target="_blank" title="道德与法治五年级下册">道德与法治五年级下册</a></h6>
<div class="con_type_link_jcdzs2020">
<a href="http://bp.pep.com.cn/ebook/ddyfzwunjxc/" target="_blank" title="阅读" class="btn_type_dy">阅读</a>
<a href="./xdjc/202002/P020200210134724185230.pdf" target="_blank" title="下载" class="btn_type_dl">下载</a>
</div>
<li class="fl js_cp">
<a href="http://bp.pep.com.cn/ebook/ddyfzliunjxc/index.html" target="_blank" title="道德与法治六年级下册"><img src="./xdjc/202002/W020200211347920284239.jpg" width="158" height="220" alt="" /></a>
<h6><a href="http://bp.pep.com.cn/ebook/ddyfzliunjxc/index.html" target="_blank" title="道德与法治六年级下册">道德与法治六年级下册</a></h6>
<div class="con_type_link_jcdzs2020">
<a href="http://bp.pep.com.cn/ebook/ddyfzliunjxc/" target="_blank" title="阅读" class="btn_type_dy">阅读</a>
<a href="./xdjc/202002/P020200210133621815755.pdf" target="_blank" title="下载" class="btn_type_dl">下载</a>
</div>
</ul>
</div>
经过分析后,我们发现:
1. 子文件夹的最外层是:<div class="con_list_jcdzs2020">,所以我们可以用BeautifulSoup库来查找所有的class属性是con_list_jcdzs2020的所有div,调用的相关代码为:find_all('div', attrs={'class':'con_list_jcdzs2020'})
2. 子文件夹名称是:“小学道德与法治教科书”。假设遍历书籍种类的每个叫做child,我们查看书籍名称就是用BeautifulSoup库中的child.div.h4.string.
3. 发现每本书籍都在一个“li”标签里面,并且class为 "fl js_cp",我们可以遍历所有的li,然后soup.find_all('li', attrs = {'class':'fl js_cp'})
3.编程逻辑:
1.获取网页的html文档。(当然用Requests库)
2.通过html文档提取课程目录,课程url,课程保存的文件夹名称),并下载。
3.输出下载的电子书数目。
4.编程代码:
以下载小学课程为例,其他内容只要修改 课程url 以及 root目录 即可
import requests
from bs4 import BeautifulSoup
import bs4
import os
'''
Date: 2020/2/25
Author: wuki
Disadvange:
只能搜索一个种类,
种类一共有8种:
1.义务教育教科书(小学)
2.义务教育教科书(初中)
3.义务教育教科书(五·四学制)小学
4.义务教育教科书(五·四学制)初中
5.特殊教育教科书
6.普通高中教科书
7.普通高中课程标准实验教科书
8.中职教科书
其中,每个文件需要修改的是:
1.课程url
2.存储的目录root改为课程种类的目录
'''
url = "https://bp.pep.com.cn/jc/ywjygjkcjc/" # 课程的URL
root = "D://book2020义务教育教科书(小学)//" # 电子书保存的目录
cnt = 0 # 统计下载的书籍数量
def getHTMLText(url): # 获取URL的HTML内容
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
def DownloadBook(bookName, bookUrl, bookCategory): # 下载书籍函数
path = root + bookCategory + '//' + bookName + ".pdf" # 书籍保存位置
try:
if not os.path.exists(root):
os.mkdir(root)
if not os.path.exists(root + bookCategory + '//'):
os.mkdir(root + bookCategory + '//')
if not os.path.exists(path):
rr = requests.get(bookUrl)
with open(path, 'wb') as f:
f.write(rr.content)
f.close()
print("书籍《{}》下载完成".format(bookName))
else:
print("文件已存在")
except Exception as e:
print("爬取失败")
print(e.args)
def TraverseClassList(html):
global cnt
soup = BeautifulSoup(html, 'html.parser')
for child in soup.find_all('div', attrs = {'class':'con_list_jcdzs2020'}):
for child2 in child.find_all('li', attrs = {'class':'fl js_cp'}):
bookCategory = child.div.h4.string
bookName = child2.a.attrs['title']
bUrl = child2.div.a.next_sibling.next_sibling.attrs['href']
bookUrl = url + bUrl[2:]
DownloadBook(bookName, bookUrl, bookCategory)
cnt += 1
# print("{}\t{}\t\t{}".format(bookName, bookCategory, bookUrl))
# print("-"* 100)
def main():
html = getHTMLText(url)
TraverseClassList(html)
print("总共下载{}本电子书籍".format(cnt))
main()
运行过程如下所示:
剩下的7个课程与上面类似,只需要修改“课程url”和“课程文件夹”即可。