101

Python 爬虫:把廖雪峰的教程转换成 PDF 电子书

_Zhijun 2017年02月15日 发布于后端 mp.weixin.qq.com

写爬虫似乎没有比用 Python 更合适了,Python 社区提供的爬虫工具多得让你眼花缭乱,各种拿来就可以直接用的 library 分分钟就可以写出一个爬虫出来,今天就琢磨着写一个爬虫,将廖雪峰的 Python 教程 爬下来做成 PDF 电子书方便大家离线阅读。

Python 爬虫:把廖雪峰的教程转换成 PDF 电子书

2017年02月15日 发布,来源:mp.weixin.qq.com

我在公众号写过很多偏概念的理论性文章,而实践类的东西写得比较少,不过这些理论知识都是从实践中总结的,理论的基础是实践,反过来理论又为实践服务。前两天,有读者在微信公众平台

问道:可以推荐一本 Python 入门的教程吗?
我说:廖雪峰的 Python 教程
她说:有没有电子书呢?
我说:没有,但你可以用 Google 搜一下,找到了记得发我一份。

然后她默默地消失在彼岸,没有了回音。我硬是去网上找了相关资源,有,但是阅读体验不好,于是趁今天有时间决定自己写个爬虫制作一本 PDF 电子书。

写爬虫似乎没有比用 Python 更合适了,Python 社区提供的爬虫工具多得让你眼花缭乱,各种拿来就可以直接用的 library 分分钟就可以写出一个爬虫出来,今天就琢磨着写一个爬虫,将廖雪峰的 Python 教程 爬下来做成 PDF 电子书方便大家离线阅读。

开始写爬虫前,我们先来分析一下该网站[1]的页面结构,网页的左侧是教程的目录大纲,每个 URL 对应到右边的一篇文章,右侧上方是文章的标题,中间是文章的正文部分,正文内容是我们关心的重点,我们要爬的数据就是所有网页的正文部分,下方是用户的评论区,评论区对我们没什么用,所以可以忽略它。

工具准备

弄清楚了网站的基本结构后就可以开始准备爬虫所依赖的工具包了。requests、beautifulsoup 是爬虫两大神器,reuqests 用于网络请求,beautifusoup 用于操作 html 数据。有了这两把梭子,干起活来利索,scrapy 这样的爬虫框架我们就不用了,小程序派上它有点杀鸡用牛刀的意思。此外,既然是把 html 文件转为 pdf,那么也要有相应的库支持, wkhtmltopdf 就是一个非常好的工具,它可以用适用于多平台的 html 到 pdf 的转换,pdfkit 是 wkhtmltopdf 的Python封装包。首先安装好下面的依赖包,接着安装 wkhtmltopdf

pip install requests
pip install beautifulsoup
pip install pdfkit

安装 wkhtmltopdf

Windows平台直接在 wkhtmltopdf 官网[2]下载稳定版的进行安装,安装完成之后把该程序的执行路径加入到系统环境 $PATH 变量中,否则 pdfkit 找不到 wkhtmltopdf 就出现错误 “No wkhtmltopdf executable found”。Ubuntu 和 CentOS 可以直接用命令行进行安装

$ sudo apt-get install wkhtmltopdf  # ubuntu
$ sudo yum intsall wkhtmltopdf      # centos

爬虫实现

一切准备就绪后就可以上代码了,不过写代码之前还是先整理一下思绪。程序的目的是要把所有 URL 对应的 html 正文部分保存到本地,然后利用 pdfkit 把这些文件转换成一个 pdf 文件。我们把任务拆分一下,首先是把某一个 URL 对应的 html 正文保存到本地,然后找到所有的 URL 执行相同的操作。

用 Chrome 浏览器找到页面正文部分的标签,按 F12 找到正文对应的 div 标签: <div class="x-wiki-content">,该 div 是网页的正文内容。用 requests 把整个页面加载到本地后,就可以使用 beautifulsoup 操作 HTML 的 dom 元素 来提取正文内容了。

具体的实现代码如下:用 soup.find_all 函数找到正文标签,然后把正文部分的内容保存到 a.html 文件中。

def parse_url_to_html(url):
   response = requests.get(url)
   soup = BeautifulSoup(response.content, "html5lib")
   body = soup.find_all(class_="x-wiki-content")[0]
   html = str(body)
   with open("a.html", 'wb') as f:
       f.write(html)

第二步就是把页面左侧所有 URL 解析出来。采用同样的方式,找到 左侧菜单标签 <ul class="uk-nav uk-nav-side">

具体代码实现逻辑:因为页面上有两个uk-nav uk-nav-side的 class 属性,而真正的目录列表是第二个。所有的 url 获取了,url 转 html 的函数在第一步也写好了。

def get_url_list():
   """
   获取所有URL目录列表
   """

   response = requests.get("http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000")
   soup = BeautifulSoup(response.content, "html5lib")
   menu_tag = soup.find_all(class_="uk-nav uk-nav-side")[1]
   urls = []
   for li in menu_tag.find_all("li"):
       url = "http://www.liaoxuefeng.com" + li.a.get('href')
       urls.append(url)
   return urls

最后一步就是把 html 转换成pdf文件了。转换成 pdf 文件非常简单,因为 pdfkit 把所有的逻辑都封装好了,你只需要调用函数 pdfkit.from_file

def save_pdf(htmls):
   """
   把所有html文件转换成pdf文件
   """

   options = {
       'page-size': 'Letter',
       'encoding': "UTF-8",
       'custom-header': [
           ('Accept-Encoding', 'gzip')
       ]
   }
   pdfkit.from_file(htmls, file_name, options=options)

执行 save_pdf 函数,电子书 pdf 文件就生成了,效果图:

总结

总共代码量加起来不到50行,不过,且慢,其实上面给出的代码省略了一些细节,比如,如何获取文章的标题,正文内容的 img 标签使用的是相对路径,如果要想在 pdf 中正常显示图片就需要将相对路径改为绝对路径,还有保存下来的 html 临时文件都要删除,这些细节末叶都放在github上。

完整代码可以上github下载 ,代码在 Windows 平台亲测有效,欢迎 fork 下载自己改进。github 地址[3],GitHub访问不了的同学可以用码云[4], 《廖雪峰的 Python 教程》电子书 PDF 文件可以通过关注本公众号『一个程序员的微站』回复 “pdf” 免费下载阅读。

长按二维码关注公众号『一个程序员的微站』 分享Python干货和有温度的内容

本文对你有帮助?分享给更多人

4.7k 浏览 371 收藏 报告 阅读模式
16 条评论
ad_4575 · 2017年02月15日

廖雪峰:麻痹,我教你python你就用来干这个?(`⌒´メ)

+3 回复

1

廖老师不会的,他的这个教程本来是免费的,网上一搜一大把pdf,epub,mobi格式的提供下载。我们讨论是技术问题

_Zhijun 分享者 · 2017年02月15日
雄起的小巨人 · 2017年02月16日

新技能Get,感觉领域可以拓宽,呼哈哈哈哈!

+1 回复

HubQin · 2017年02月16日

great!

+1 回复

mcglandy · 2017年02月15日

廖雪峰哭晕在厕所

+1 回复

搬砖大叔 · 2017年02月15日

廖雪峰哭晕在厕所

+1 回复

蓝光95 · 2017年11月29日

我修正了,爬取了几个网页,结果就被查封了,连浏览器都报 503 了,哭晕在厕所。

回复

景云之应 · 2017年07月05日

windows 上安装beautifulsoup失败 Command "python setup.py egg_info" failed with error code 1 in C:UsersFANBIN~1AppDataLocalTemppip-build-edf_r5pybeautifulsoup,,,,有人知道怎么解决吗

回复

Rafeal · 2017年06月12日

棒极了

回复

键盘侠 · 2017年06月03日

厉害了

回复

hzde0128 · 2017年03月27日

不错,学习了

回复

robin · 2017年02月21日

开了眼界,学了知识,谢谢!

回复

mengdu · 2017年02月18日

爬虫爬广告能不能赚钱?

回复

飞扬 · 2017年02月16日

爬虫小白有个问题,beautifusoup 和Xpath 哪个更好用一些呢?
我一直用的是Xpath,但看到很多人都在用beautifulsoup。

回复

0

都可以,哪个熟悉用哪个,能解决问题就行

_Zhijun 分享者 · 2017年02月17日
Ramesy · 2017年02月16日

感觉用lxml和soupstrainer会快点

回复

载入中...