Python爬取廖雪峰教程存为PDF

欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!

对商业智能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

3901436-e8712415cfc61b30

将单个html解析成单个pdf文件

合并成pdf

3901436-19be254e203ab37d

最后合并的文件

内容:

3901436-d4b594e5c2d8f0f0

最后的pdf文件

最新更新:按照这个代码目前无法抓取,因为廖老师把网站改成https了。对应代码要做修改。

而且Requests 请求里需要加入User-agent模拟浏览器请求,就可以了。

PDF放到百度网盘了,公众号回复PDF教程,别忘了去谢谢廖老师~

Python爱好者社区历史文章大合集

Python爱好者社区历史文章列表(每周append更新一次)

福利:文末扫码立刻关注公众号,“Python爱好者社区”,开始学习Python课程:

3901436-a3db01f0e83f80e3

关注后在公众号内回复“课程”即可获取:

小编的转行入职数据科学(数据分析挖掘/机器学习方向)【最新免费】

小编的Python入门免费视频课程!!!

小编的Python快速上手matplotlib可视化库!!!

崔老师爬虫实战案例免费学习视频。

陈老师数据分析报告制作免费学习视频。

玩转大数据分析!Spark2.X+Python 精华实战课程免费学习视频。

3901436-0e1a8fa67b75baf8
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值