Bagaimana mengubah halaman web menjadi PDF dengan menggunakan Python

97

Saya menemukan solusi untuk mencetak halaman web menjadi PDF file lokal, menggunakan Python. salah satu solusi yang baik adalah dengan menggunakan Qt, ditemukan di sini, https://bharatikunal.wordpress.com/2010/01/ .

Itu tidak berfungsi pada awalnya karena saya mengalami masalah dengan instalasi PyQt4 karena memberikan pesan kesalahan seperti ' ImportError: No module named PyQt4.QtCore', dan ' ImportError: No module named PyQt4.QtCore'.

Itu karena PyQt4 tidak diinstal dengan benar. Saya dulu memiliki perpustakaan yang terletak di C: \ Python27 \ Lib namun bukan untuk PyQt4.

Bahkan, itu hanya perlu mengunduh dari http://www.riverbankcomputing.com/software/pyqt/download (ingat versi Python yang benar yang Anda gunakan), dan instal ke C: \ Python27 (kasus saya). Itu dia.

Sekarang skripnya berjalan dengan baik jadi saya ingin membagikannya. untuk opsi lainnya dalam menggunakan Qprinter, silakan lihat http://qt-project.org/doc/qt-4.8/qprinter.html#Orientation-enum .

Mark K
sumber

Jawaban:

159

Anda juga dapat menggunakan pdfkit :

Pemakaian

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

Install

MacOS: brew install Caskroom/cask/wkhtmltopdf

Debian / Ubuntu: apt-get install wkhtmltopdf

Windows: choco install wkhtmltopdf

Lihat dokumentasi resmi untuk MacOS / Ubuntu / OS lain: https://github.com/JazzCore/python-pdfkit/wiki/Installing-wkhtmltopdf

NorthCat
sumber
4
Ini luar biasa, jauh lebih mudah daripada mengotak-atik reportlab atau menggunakan drive cetak untuk mengonversi. Terima kasih banyak.
Janda
@NorthCat dapatkah kamu memberikan contoh lain tentang mengubah tabel html dengan pdfkit?
Babel
1
Sepertinya windows tidak mendukung pdfkit. Benarkah itu?
Kane Chew
2
Sempurna !! Bahkan unduh gambar yang disematkan, jangan repot-repot menggunakannya! Anda harusapt-get install wkhtmltopdf
Tinmarino
4
pdfkit bergantung pada paket non-python wkhtmltopdf, yang pada gilirannya membutuhkan server X yang sedang berjalan. Jadi meskipun bagus di beberapa lingkungan, ini bukan jawaban yang berfungsi secara umum di python.
Rasmus Kaj
47

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
sumber
5
Dapatkah saya memberikan jalur file sebagai ganti url?
Piyush S. Wanare
12
Saya pikir saya akan lebih suka proyek ini karena dependensinya adalah paket python daripada paket sistem. Pada Jan 2018 tampaknya pembaruan lebih sering dan dokumentasi yang lebih baik.
stv
4
Ada terlalu banyak hal untuk dipasang. Saya berhenti di libpango dan memilih pdfkit. Tidak baik untuk wkhtmltopdf di seluruh sistem tetapi weasyprint juga memerlukan beberapa penginstalan di seluruh sistem.
Visoft
1
Saya percaya pilihannya harus 'wb', bukan 'w', karena pdfitu bytesobjek.
Anatoly Scherbakov
1
bagi saya itu hanya mengunduh halaman pertama dan mengabaikan sisanya
Fábio
24

terima kasih untuk posting di bawah ini, dan saya dapat menambahkan alamat tautan halaman web untuk dicetak dan sekarang pada PDF yang dihasilkan, tidak peduli berapa banyak halaman yang dimilikinya.

Tambahkan teks ke PDF yang Ada menggunakan Python

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

Untuk membagikan script seperti di bawah ini:

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
sumber
Terima kasih telah membagikan kode Anda! Adakah saran untuk membuat ini berfungsi untuk file pdf lokal? Atau semudah memasukkan "file: ///" ke url? Saya tidak terlalu akrab dengan perpustakaan ini ... terima kasih
user2426679
@ user2426679, maksud Anda mengonversi PDF online menjadi file PDF lokal?
Mark K
terima kasih atas balasan anda ... maaf atas keterlambatan saya. Saya akhirnya menggunakan wkhtmltopdf karena dapat menangani apa yang saya lemparkan. Tapi saya bertanya bagaimana memuat pdf yang lokal ke hdd saya. Salam
pengguna2426679
@ user2426679 maaf saya masih belum mengerti. mungkin karena saya juga pemula di Python. Maksud Anda membaca file PDF lokal dengan Python?
Mark K
Ada beberapa masalah dengan html5lib, yang digunakan oleh xhtml2pdf. Solusi ini memperbaiki masalah: github.com/xhtml2pdf/xhtml2pdf/issues/318
Blairg23
14

ini yang berfungsi dengan baik:

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
sumber
Menariknya, tautan halaman web dihasilkan sebagai teks daripada tautan dalam PDF yang dihasilkan.
amergin
1
Adakah yang tahu mengapa ini akan menghasilkan pdf kosong untuk saya?
boson
11

Berikut adalah solusi sederhana menggunakan QT. Saya menemukan ini sebagai bagian dari jawaban untuk pertanyaan berbeda di StackOverFlow. Saya mengujinya di 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!"
Jim Paul
sumber
4

Saya mencoba jawaban @NorthCat menggunakan pdfkit.

Diperlukan wkhtmltopdf untuk diinstal. Penginstalan dapat diunduh dari sini. https://wkhtmltopdf.org/downloads.html

Instal file yang dapat dieksekusi. Kemudian tulis sebuah baris untuk menunjukkan dimana wkhtmltopdf, seperti di bawah ini. (direferensikan dari Tidak dapat membuat pdf menggunakan python PDFKIT Kesalahan: "Tidak ditemukan wkhtmltopdf yang dapat dieksekusi:"

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
sumber
kemana perginya setelah saya mengklik .deb dan menginstal di pusat perangkat lunak?
mLstudent33
2

Solusi ini berfungsi untuk saya menggunakan PyQt5 versi 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
sumber
1

Jika Anda menggunakan selenium dan chromium, Anda tidak perlu mengelola cookie sendiri, dan Anda dapat membuat halaman pdf dari cetakan chromium sebagai pdf. Anda dapat merujuk proyek ini untuk merealisasikannya. https://github.com/maxvst/python-selenium-chrome-html-to-pdf-converter

dasar yang dimodifikasi> 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
sumber
1
Pertama saya menggunakan weasyprint tetapi tidak mendukung cookie bahkan Anda dapat menulis sendiri default_url_fetcheruntuk menangani cookie tetapi kemudian saya terjadi masalah ketika menginstalnya di Ubuntu16. Kemudian saya menggunakan wkhtmltopdf itu mendukung pengaturan cookie tetapi itu menyebabkan banyak OSERROR seperti -15 -11 saat menangani beberapa halaman.
Yuanmeng Xiao
Terima kasih telah berbagi dengan Tuan @Yuanmeng Xiao.
Mark K