python将html存为pdf_使用 Python 将 HTML 转成 PDF

背景

很多人应该经常遇到在网上看到好的学习教程和资料但却没有电子档的,心里顿时痒痒,

下述指导一下大家,如何将网站上的各类教程转换成 PDF 电子书。

关键核心

主要使用的是wkhtmltopdf的Python封装—【pdfkit】

环境安装

python3系列

pip install requests

pip install beautifulsoup4

pip install pdfkit

如果是liunx系,则 sudo yum intsall wkhtmltopdf

如果是windows系,则下载稳定版的 wkhtmltopdf 进行安装,安装完成之后把该程序的执行路径加入到系统环境 $PATH 变量中

牛刀小试

一个简单的例子:

import pdfkit pdfkit.from_url('http://google.com', 'out.pdf')

pdfkit.from_file('test.html', 'out.pdf')

pdfkit.from_string('Hello!', 'out.pdf')

你也可以传递一个url或者文件名列表:

pdfkit.from_url(['google.com', 'yandex.ru', 'engadget.com'], 'out.pdf')

pdfkit.from_file(['file1.html', 'file2.html'], 'out.pdf')

也可以传递一个打开的文件:

with open('file.html') as f:

pdfkit.from_file(f, 'out.pdf')

实例代码实现

如将自强学堂中的django教程,生成一个pdf文件

#coding=utf-8

from __future__ import unicode_literals

import os,sys,re,time

import requests,codecs

from bs4 import BeautifulSoup

from urllib.parse import urlparse

import pdfkit

import platform

requests.packages.urllib3.disable_warnings()

system=platform.system()

print(sys.getdefaultencoding())

str_encode='gbk' if system is 'Windows' else 'utf-8'

print(str_encode)

html_template = """

{content}

"""

if not os.path.exists(os.path.join(os.path.dirname(__file__),'html')):

os.mkdir(os.path.join(os.path.dirname(__file__),'html'))

url_list=[]

start_url='http://www.ziqiangxuetang.com/django/django-tutorial.html'

# s=requests.session()

# html_doc=s.get('{}'.format(start_url),verify=False).content

# soup = BeautifulSoup(html_doc,'html.parser')

# print(soup.prettify())

def get_url_list(url):

"""

获取所有URL目录列表

:return:

"""

last_position = find_last(url, "/") + 1

tutorial_url_head = url[0:last_position]

domain = get_domain(url) + "/"

print(domain)

response = requests.get(url)

soup = BeautifulSoup(response.content, "html.parser")

urls = []

for a in soup.find_all("a"):

href = str(a.get('href'))

result = href.find('/')

if result == -1:

url = tutorial_url_head + href

else:

url = domain + href

if 'django' in url:

urls.append(url)

return urls

def find_last(string, char):

last_position = -1

while True:

position = string.find(char, last_position + 1)

if position == -1:

return last_position

last_position = position

def get_domain(url):

r = urlparse(url)

return r.scheme + "://" + r.netloc

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_="w-col l10 m12")

h = str(body)

html = h[1:-1]

html = html_template.format(content=html)

html = html.encode("utf-8")

title=soup.title.get_text()

print(url)

with open('{}/{}'.format(os.path.join(os.path.dirname(__file__),'html'),name), 'wb') as f:

f.write(html)

return '{}/{}'.format(os.path.join(os.path.dirname(__file__),'html'),name)

except Exception as e:

print(e)

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)

def main():

start = time.time()

urls = get_url_list(start_url)

htmls = [parse_url_to_html(url, str(index) + ".html") for index, url in enumerate(urls)]

print(htmls)

try:

save_pdf(htmls, 'cralwer_{}.pdf'.format(time.strftime('%Y_%m_%d_%H_%M_%S')))

except Exception as e:

print(e)

for html in htmls:

os.remove(html)

total_time = time.time() - start

print(u"总共耗时:{0:.2f}秒".format(total_time))

main()

大概思路

然后,通过爬虫获取所有含django的url地址,存放在一个列表中,然后再依次获取url,解析各个url中的正文body内容,通过人工分析,各个url正文Body对应的class为w-col l10 m12,所以只需要爬取w-col l10 m12的内容即可。

将获取到的正文内容存放在html文件中,最终返回一个含所有html文件地址的列表htmls。

通过pdfkit.from_file接收一个htmls列表,生成对应pdf文件。

常见问题

IOError: ‘No wkhtmltopdf executable found’

确保 wkhtmltopdf 在你的系统路径中($PATH),会通过 configuration进行了配置 (详情看上文描述)。 在Windows系统中使用where wkhtmltopdf命令 或 在 linux系统中使用 which wkhtmltopdf 会返回 wkhtmltopdf二进制可执行文件所在的确切位置.

IOError: ‘Command Failed’

如果出现这个错误意味着 PDFKit不能处理一个输入。你可以尝试直接在错误信息后面直接运行一个命令来查看是什么导致了这个错误 (某些版本的 wkhtmltopdf会因为段错误导致处理失败

正常生成,但是出现中文乱码

在html中加入

参考

欢迎订阅号

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值