对商业智能 BI, 大数据分析挖掘, 机器学习, python,R 等数据领域感兴趣的同学加微信: tsaiedu, 并注明消息来源, 邀请你进入数据爱好者交流群, 数据爱好者们都在这儿.
作者: 欧巴 Python 爱好者社区专栏作者 知乎专栏: Python 学习之路 https://zhuanlan.zhihu.com/pythonlearn
首先感谢廖老师给我们大家提供的那么好的教程, 相信大部分童鞋都看过廖老师的 python 教程, 我也是从这个教程入了门. 后来又开始接着学 JavaScript, 不过每次都要用浏览器上网浏览太麻烦, 所以就用爬虫爬下来保存为 PDF 格式. 不过缺点就是没有目录废话不多说上代码.
- # coding=utf-8
- import os
- import re
- import time
- import pdfkit
- import requests
- from bs4 import BeautifulSoup
- from PyPDF2 import PdfFileMerger,PdfFileReader, PdfFileWriter
- import sys
- #test12
- html_template = """
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- </head>
- <body>
- {content}
- </body>
- </html>
- """path_wk = r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe' #安装位置
- config = pdfkit.configuration(wkhtmltopdf = path_wk)
- #----------------------------------------------------------------------
- def parse_url_to_html(url, name):
- """
- 解析 URL, 返回 HTML 内容
- :param url: 解析的 url
- :param name: 保存的 html 文件名
- :return: html
- """
- try:
- response = requests.get(url)
- soup = BeautifulSoup(response.content, 'html.parser')
- # 正文
- body = soup.find_all(class_="x-wiki-content")[0]
- # 标题
- title = soup.find('h4').get_text()
- # 标题加入到正文的最前面, 居中显示
- center_tag = soup.new_tag("center")
- title_tag = soup.new_tag('h1')
- title_tag.string = title
- center_tag.insert(1, title_tag)
- body.insert(1, center_tag)
- HTML = str(body)
- # body 中的 img 标签的 src 相对路径的改成绝对路径
- pattern = "(<img .*?src=\")(.*?)(\")"
- def func(m):
- if not m.group(3).startswith("http"):
- rtn = m.group(1) + "http://www.liaoxuefeng.com" + m.group(2) + m.group(3)
- return rtn
- else:
- return m.group(1)+m.group(2)+m.group(3)
- HTML = re.compile(pattern).sub(func, HTML)
- HTML = html_template.format(content=HTML)
- HTML = HTML.encode("utf-8")
- with open(name, 'wb') as f:
- f.write(HTML)
- return name
- except Exception as e:
- print ("解析错误!")
- #----------------------------------------------------------------------
- def get_url_list():
- """
- 获取所有 URL 目录列表
- :return:
- """response = requests.get("http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000")
- soup = BeautifulSoup(response.content, "html.parser")
- menu_tag = soup.find_all(class_="uk-nav uk-nav-side")[1]
- urls = []
- for li in menu_tag.find_all("div"):
- url = "http://www.liaoxuefeng.com" + li.a.get('href')
- urls.append(url)
- return urls
- #----------------------------------------------------------------------
- def save_pdf(htmls, file_name):
- """
- 把所有 html 文件保存到 pdf 文件
- :param htmls: html 文件列表
- :param file_name: pdf 文件名
- :return:
- """options = {'page-size':'Letter','margin-top':'0.75in','margin-right':'0.75in','margin-bottom':'0.75in','margin-left':'0.75in','encoding':"UTF-8",'custom-header': [
- ('Accept-Encoding', 'gzip')
- ],
- 'cookie': [
- ('cookie-name1', 'cookie-value1'),
- ('cookie-name2', 'cookie-value2'),
- ],
- 'outline-depth': 10,
- }
- pdfkit.from_file(htmls, file_name, options=options,configuration=config)
- #----------------------------------------------------------------------
- def main():
- start = time.time()
- file_name = u"liaoxuefeng_Python3_tutorial"
- urls = get_url_list()
- for index, url in enumerate(urls):
- parse_url_to_html(url, str(index) + ".html")
- htmls =[]
- pdfs =[]
- print(len(urls))
- for i in range(len(urls)):
- htmls.append(str(i)+'.html')
- pdfs.append(file_name+str(i)+'.pdf')
- save_pdf(str(i)+'.html', file_name+str(i)+'.pdf')
- print (u"转换完成第"+str(i)+'个 html')
- print(pdfs)
- pdf_output = PdfFileWriter()
- for PDF in pdfs:
- pdf_input = PdfFileReader(open(PDF,'rb'))
- page_count = pdf_input.getNumPages()
- print(page_count)
- for i in range(page_count):
- pdf_output.addPage(pdf_input.getPage(i))
- output = open(u"廖雪峰 Python_all.pdf", "wb")
- pdf_output.write(output)
- print (u"输出 PDF 成功!")
- for HTML in htmls:
- os.remove(HTML)
- print (u"删除临时文件"+HTML)
- for PDF in pdfs:
- os.remove(PDF)
- print (u"删除临时文件"+PDF)
- total_time = time.time() - start
- print(u"总共耗时:%f 秒" % total_time)
- #----------------------------------------------------------------------
- def changeDir(dir_name):
- """目录切换"""
- if not os.path.exists(dir_name):
- os.mkdir(dir_name)
- os.chdir(dir_name)
- #----------------------------------------------------------------------
- if __name__ == '__main__':
- #存放文件的路径
- dir_name = 'c:\\12'
- changeDir(dir_name)
- main()
代码很简单, 就是获取所有博客左侧导航栏对应的所有 URL, 然后将每个 url 解析出来保存成 HTML, 再将每个 HTML 保存成单个 PDF 文件, 最后合并 PDF 文件. 需要注意的是 windwos 下需要安装 wkhtmltopdf.exe 这个软件, 并在 python 代码里指明这个程序的路径. 不然合并时会报错.
下载 HTML 保存成 PDF
将单个 HTML 解析成单个 PDF 文件
合并成 PDF
最后合并的文件
内容:
最后的 PDF 文件
最新更新: 按照这个代码目前无法抓取, 因为廖老师把网站改成 https 了. 对应代码要做修改.
而且 Requests 请求里需要加入 User-agent 模拟浏览器请求, 就可以了.
PDF 放到百度网盘了, 公众号回复 PDF 教程, 别忘了去谢谢廖老师~
Python 爱好者社区历史文章大合集:
Python 爱好者社区历史文章列表 (每周 append 更新一次)
福利: 文末扫码立刻关注公众号,"Python 爱好者社区", 开始学习 Python 课程:
关注后在公众号内回复 "课程" 即可获取:
小编的转行入职数据科学 (数据分析挖掘 / 机器学习方向)[最新免费]
小编的 Python 入门免费视频课程!!!
小编的 Python 快速上手 matplotlib 可视化库!!!
崔老师爬虫实战案例免费学习视频.
陈老师数据分析报告制作免费学习视频.
玩转大数据分析! Spark2.X+Python 精华实战课程免费学习视频.
来源: http://www.jianshu.com/p/ac4fc30709cb