So konvertieren Sie eine Webseite mithilfe von Python in PDF

90

Ich habe eine Lösung gefunden, um eine Webseite mit Python in eine lokale PDF-Datei zu drucken. Eine der guten Lösungen ist die Verwendung von Qt, das Sie hier finden: https://bharatikunal.wordpress.com/2010/01/ .

Es hat am Anfang nicht funktioniert, da ich Probleme mit der Installation von PyQt4 hatte, weil es Fehlermeldungen wie ' ImportError: No module named PyQt4.QtCore' und ' ImportError: No module named PyQt4.QtCore' gab.

Dies lag daran, dass PyQt4 nicht richtig installiert wurde. Früher befanden sich die Bibliotheken unter C: \ Python27 \ Lib, aber nicht für PyQt4.

Tatsächlich muss es einfach von http://www.riverbankcomputing.com/software/pyqt/download heruntergeladen werden (beachten Sie die richtige Python-Version, die Sie verwenden) und unter C: \ Python27 (mein Fall) installieren. Das ist es.

Jetzt laufen die Skripte einwandfrei und ich möchte sie teilen. Weitere Optionen zur Verwendung von Qprinter finden Sie unter http://qt-project.org/doc/qt-4.8/qprinter.html#Orientation-enum .

Mark K.
quelle

Antworten:

150

Sie können auch pdfkit verwenden :

Verwendung

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

Installieren

Mac OS: brew install Caskroom/cask/wkhtmltopdf

Debian / Ubuntu: apt-get install wkhtmltopdf

Windows: choco install wkhtmltopdf

Siehe offizielle Dokumentation für MacOS / Ubuntu / andere Betriebssysteme: https://github.com/JazzCore/python-pdfkit/wiki/Installing-wkhtmltopdf

NorthCat
quelle
4
Dies ist fantastisch, viel einfacher als mit Reportlab herumzuspielen oder ein Drucklaufwerk zum Konvertieren zu verwenden. Vielen Dank.
Dowlers
@NorthCat Kannst du ein weiteres Beispiel zum Konvertieren von HTML-Tabellen mit pdfkit geben?
Babel
1
Es scheint, dass Windows pdfkit nicht unterstützt. Ist das wahr?
Kane Chew
2
Perfekt !! Laden Sie auch die eingebetteten Bilder herunter, verwenden Sie das nicht! Sie müssenapt-get install wkhtmltopdf
Tinmarino
4
pdfkit hängt vom Nicht-Python-Paket wkhtmltopdf ab, für das wiederum ein laufender X-Server erforderlich ist. Obwohl dies in einigen Umgebungen nett ist, ist dies keine Antwort, die im Allgemeinen in Python funktioniert.
Rasmus Kaj
43

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)
JohnMudd
quelle
4
Kann ich anstelle der URL einen Dateipfad angeben?
Piyush S. Wanare
11
Ich denke, ich werde dieses Projekt bevorzugen, da es sich bei den Abhängigkeiten eher um Python-Pakete als um ein Systempaket handelt. Ab Januar 2018 scheint es häufigere Updates und eine bessere Dokumentation zu geben.
stv
3
Es sind zu viele Dinge zu installieren. Ich blieb bei libpango stehen und holte mir das pdfkit. Böse für systemweites wkhtmltopdf, aber für weasyprint sind auch einige systemweite Installationen erforderlich.
Visoft
1
Ich würde glauben, dass die Option 'wb'nicht sein sollte 'w', weil pdfes sich um ein bytesObjekt handelt.
Anatoly Scherbakov
1
für mich lädt es nur die erste Seite herunter und ignoriert den Rest
Fábio
23

Dank der folgenden Beiträge kann ich die zu druckende Webseiten-Linkadresse hinzufügen und die aktuelle Zeit für das generierte PDF anzeigen, unabhängig davon, wie viele Seiten es enthält.

Fügen Sie mit Python Text zu vorhandenen PDF-Dateien hinzu

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

So teilen Sie das Skript wie folgt:

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.'
Mark K.
quelle
Vielen Dank, dass Sie Ihren Code geteilt haben! Irgendwelche Ratschläge, damit dies für lokale PDF-Dateien funktioniert? Oder ist es so einfach, der Datei "file: ///" voranzustellen? Ich bin nicht sehr vertraut mit diesen Bibliotheken ... danke
user2426679
@ user2426679, meinst du Online-PDF in lokale PDF-Dateien konvertieren?
Mark K
Danke für deine Antwort ... Entschuldigung für meine Verspätung. Am Ende habe ich wkhtmltopdf verwendet, da es mit dem umgehen konnte, was ich darauf warf. Aber ich habe gefragt, wie ich ein PDF laden soll, das lokal auf meiner Festplatte ist. Cheers
user2426679
@ user2426679 Entschuldigung, ich verstehe dich immer noch nicht. Vielleicht, weil ich auch ein Neuling in Python bin. Sie wollten lokale PDF-Dateien in Python lesen?
Mark K
Es gab einige Probleme mit html5lib, die von xhtml2pdf verwendet werden. Diese Lösung hat das Problem behoben: github.com/xhtml2pdf/xhtml2pdf/issues/318
Blairg23
14

Hier ist derjenige, der gut funktioniert:

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_())
Mark K.
quelle
Interessanterweise werden die Webseiten-Links als Text und nicht als Links in der generierten PDF-Datei generiert.
Amergin
Weiß jemand, warum dies leere PDFs für mich erzeugen würde?
Boson
11

Hier ist eine einfache Lösung mit QT. Ich fand dies als Teil einer Antwort auf eine andere Frage in StackOverFlow. Ich habe es unter Windows getestet.

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!"
Jim Paul
quelle
2

Ich habe versucht, @NorthCat Antwort mit pdfkit zu beantworten.

Es musste wkhtmltopdf installiert sein. Die Installation kann hier heruntergeladen werden. https://wkhtmltopdf.org/downloads.html

Installieren Sie die ausführbare Datei. Schreiben Sie dann eine Zeile, um anzugeben, wo sich wkhtmltopdf befindet (siehe unten). (referenziert von Kann kein PDF mit Python PDFKIT erstellen Fehler: "Keine ausführbare Datei für wkhtmltopdf gefunden:"

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)
Mark K.
quelle
1

Wenn Sie Selen und Chrom verwenden, müssen Sie Cookies nicht selbst verwalten, und Sie können eine PDF-Seite aus dem Druck von Chrom als PDF erstellen. Sie können dieses Projekt referenzieren, um es zu realisieren. https://github.com/maxvst/python-selenium-chrome-html-to-pdf-converter

geänderte Basis> 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 = "/programming/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()
Yuanmeng Xiao
quelle
1
Erstens verwende ich weasyprint, aber es unterstützt keine Cookies, auch wenn Sie Ihre eigenen schreiben können default_url_fetcher, um Cookies zu verarbeiten. Später tritt jedoch ein Problem auf, wenn ich es in Ubuntu16 installiere. Dann verwende ich wkhtmltopdf, um die Cookie-Einstellung zu unterstützen, aber es verursacht viele OSERROR wie -15 -11 beim Handle eine Seite.
Yuanmeng Xiao
Vielen Dank für das Teilen von Herrn @ Yuanmeng Xiao.
Mark K
1

Diese Lösung funktionierte für mich mit 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('/programming/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_())
Y.kh.
quelle