Python爬取廖雪峰教程存为PDF

浏览: 1282

作者:欧巴        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 精华实战课程免费学习视频。

推荐 0
本文由 Python爱好者社区 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册