如何使用 Python 将网页转换成 PDF

我正在寻找解决方案,打印网页到本地文件 PDF,使用 Python。一个好的解决方案是使用 Qt,在这里找到 https://bharatikunal.wordpress.com/2010/01/

由于 PyQt4的安装出现了问题,所以一开始它并不能正常工作,因为它提供了错误消息,比如‘ ImportError: No module named PyQt4.QtCore’和‘ ImportError: No module named PyQt4.QtCore’。

这是因为 PyQt4没有正确安装。 我曾经把库放在 C: Python27Lib 上,但是它不适用于 PyQt4。

实际上,它只需要从 http://www.riverbankcomputing.com/software/pyqt/download下载(注意您正在使用的正确的 Python 版本) ,并将其安装到 C: Python27(我的示例)。就是这样。

现在脚本运行良好,所以我想分享它。有关使用 QQ 打印机的更多选项,请参阅 http://qt-project.org/doc/qt-4.8/qprinter.html#Orientation-enum

277448 次浏览

下面是一个很好的例子:

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *


app = QApplication(sys.argv)
web = QWebView()
web.load(QUrl("http://www.yahoo.com"))
printer = QPrinter()
printer.setPageSize(QPrinter.A4)
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName("fileOK.pdf")


def convertIt():
web.print_(printer)
print("Pdf generated")
QApplication.exit()


QObject.connect(web, SIGNAL("loadFinished(bool)"), convertIt)
sys.exit(app.exec_())

感谢下面的文章,我能够添加在网页上的链接地址打印和目前的 PDF 生成的时间,无论它有多少页。

使用 Python 向现有 PDF 添加文本

Https://github.com/disflux/django-mtr/blob/master/pdfgen/doc_overlay.py

分享脚本如下:

import time
from pyPdf import PdfFileWriter, PdfFileReader
import StringIO
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from xhtml2pdf import pisa
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *


url = 'http://www.yahoo.com'
tem_pdf = "c:\\tem_pdf.pdf"
final_file = "c:\\younameit.pdf"


app = QApplication(sys.argv)
web = QWebView()
#Read the URL given
web.load(QUrl(url))
printer = QPrinter()
#setting format
printer.setPageSize(QPrinter.A4)
printer.setOrientation(QPrinter.Landscape)
printer.setOutputFormat(QPrinter.PdfFormat)
#export file as c:\tem_pdf.pdf
printer.setOutputFileName(tem_pdf)


def convertIt():
web.print_(printer)
QApplication.exit()


QObject.connect(web, SIGNAL("loadFinished(bool)"), convertIt)


app.exec_()
sys.exit


# Below is to add on the weblink as text and present date&time on PDF generated


outputPDF = PdfFileWriter()
packet = StringIO.StringIO()
# create a new PDF with Reportlab
can = canvas.Canvas(packet, pagesize=letter)
can.setFont("Helvetica", 9)
# Writting the new line
oknow = time.strftime("%a, %d %b %Y %H:%M")
can.drawString(5, 2, url)
can.drawString(605, 2, oknow)
can.save()


#move to the beginning of the StringIO buffer
packet.seek(0)
new_pdf = PdfFileReader(packet)
# read your existing PDF
existing_pdf = PdfFileReader(file(tem_pdf, "rb"))
pages = existing_pdf.getNumPages()
output = PdfFileWriter()
# add the "watermark" (which is the new pdf) on the existing page
for x in range(0,pages):
page = existing_pdf.getPage(x)
page.mergePage(new_pdf.getPage(0))
output.addPage(page)
# finally, write "output" to a real file
outputStream = file(final_file, "wb")
output.write(outputStream)
outputStream.close()


print final_file, 'is ready.'

你也可以使用 Pdf 工具箱:

用法

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

安装

MacOS: brew install Caskroom/cask/wkhtmltopdf

Debian/Ubuntu: apt-get install wkhtmltopdf

视窗: choco install wkhtmltopdf

请参阅 MacOS/Ubuntu/other OS 的官方文档: https://github.com/JazzCore/python-pdfkit/wiki/Installing-wkhtmltopdf

下面是一个使用 QT 的简单解决方案。我发现这是对 StackOverFlow 上另一个问题的部分回答。我在 Windows 上测试过。

from PyQt4.QtGui import QTextDocument, QPrinter, QApplication


import sys
app = QApplication(sys.argv)


doc = QTextDocument()
location = "c://apython//Jim//html//notes.html"
html = open(location).read()
doc.setHtml(html)


printer = QPrinter()
printer.setOutputFileName("foo.pdf")
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setPageSize(QPrinter.A4);
printer.setPageMargins (15,15,15,15,QPrinter.Millimeter);


doc.print_(printer)
print "done!"

WeasyPrint

pip install weasyprint  # No longer supports Python 2.x.


python
>>> import weasyprint
>>> pdf = weasyprint.HTML('http://www.google.com').write_pdf()
>>> len(pdf)
92059
>>> open('google.pdf', 'wb').write(pdf)

根据这个答案: 如何使用 Python 将网页转换成 PDF,建议使用 译自: 美国《科学》杂志网站(https://pypi.python.org/pypi/pdfkit)。您还必须安装 一个 href = “ https://wkhtmltopdf.org/downloads.html”rel = “ noReferrer”> wkhtmltopdf

如果您有一个本地 .html文件,那么您需要使用以下命令:

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

但是如果没有将 wkhtmltopdf 可执行文件添加到系统路径中,这将抛出一个错误。这就是让我犯错的地方,我想和大家分享。

在 Windows 中,打开您的环境变量并将它们添加到 System variables > Path中,如下所示。对我来说,这些。在我从一个 exe 安装 wkhtmltopdf 之后,exe文件位于这里:

C:\Program Files\wkhtmltopdf\bin

environment variables

我试着用 pdfkit 来回答@NorthCat。

It required wkhtmltopdf to be installed. The install can be downloaded from here. https://wkhtmltopdf.org/downloads.html

安装可执行文件。然后写一行来指示 wkhtmltopdf 的位置,如下所示

import pdfkit




path_wkthmltopdf = "C:\\Folder\\where\\wkhtmltopdf.exe"
config = pdfkit.configuration(wkhtmltopdf = path_wkthmltopdf)


pdfkit.from_url("http://google.com", "out.pdf", configuration=config)

如果你使用硒和铬,你不需要管理自己的 cookie,你可以生成 pdf 页面从铬的打印作为 pdf。 您可以引用这个项目来实现它。 Https://github.com/maxvst/python-selenium-chrome-html-to-pdf-converter

改良基地 > https://github.com/maxvst/python-selenium-chrome-html-to-pdf-converter/blob/master/sample/html_to_pdf_converter.py

import sys
import json, base64




def send_devtools(driver, cmd, params={}):
resource = "/session/%s/chromium/send_command_and_get_result" % driver.session_id
url = driver.command_executor._url + resource
body = json.dumps({'cmd': cmd, 'params': params})
response = driver.command_executor._request('POST', url, body)
return response.get('value')




def get_pdf_from_html(driver, url, print_options={}, output_file_path="example.pdf"):
driver.get(url)


calculated_print_options = {
'landscape': False,
'displayHeaderFooter': False,
'printBackground': True,
'preferCSSPageSize': True,
}
calculated_print_options.update(print_options)
result = send_devtools(driver, "Page.printToPDF", calculated_print_options)
data = base64.b64decode(result['data'])
with open(output_file_path, "wb") as f:
f.write(data)






# example
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


url = "https://stackoverflow.com/questions/23359083/how-to-convert-webpage-into-pdf-by-using-python#"
webdriver_options = Options()
webdriver_options.add_argument("--no-sandbox")
webdriver_options.add_argument('--headless')
webdriver_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(chromedriver, options=webdriver_options)
get_pdf_from_html(driver, url)
driver.quit()

This solution worked for me using PyQt5 version 5.15.0

import sys
from PyQt5 import QtWidgets, QtWebEngineWidgets
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QPageLayout, QPageSize
from PyQt5.QtWidgets import QApplication


if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
loader = QtWebEngineWidgets.QWebEngineView()
loader.setZoomFactor(1)
layout = QPageLayout()
layout.setPageSize(QPageSize(QPageSize.A4Extra))
layout.setOrientation(QPageLayout.Portrait)
loader.load(QUrl('https://stackoverflow.com/questions/23359083/how-to-convert-webpage-into-pdf-by-using-python'))
loader.page().pdfPrintingFinished.connect(lambda *args: QApplication.exit())


def emit_pdf(finished):
loader.page().printToPdf("test.pdf", pageLayout=layout)


loader.loadFinished.connect(emit_pdf)
sys.exit(app.exec_())

正如另一个答案所解释的那样,如果您在本地有. html 文件,那么您可以使用以下内容:

pdfkit.from_file('abc.html', 'abc.pdf')

此外,如果你的源 html 文件有 img 标签,src 应该是相对路径,你必须包含这个选项,以允许本地文件访问。

pdfkit.from_file('abc.html', 'abc.pdf',options={"enable-local-file-access": ""})

否则,您可能会遇到以下错误

错误: wkhtmltopdf 报告了一个错误: 由于 网络错误: ProtocolUnknown 错误

来源: Https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2660#issuecomment-663063752

Pdfkit 错误: 由于网络错误以代码1退出: ProtocolUnknown nError