查看原文
其他

Python爬取廖雪峰教程存为PDF

欧巴 Python爱好者社区 2019-04-07

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


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存