Python kullanarak web sayfasını PDF'ye dönüştürme


97

Python kullanarak web sayfasını yerel dosya PDF'ye yazdırmak için bir çözüm buluyordum. iyi çözümlerden biri, https://bharatikunal.wordpress.com/2010/01/ adresinde bulunan Qt'yi kullanmaktır .

PyQt4 kurulumunda sorun yaşadığım için başlangıçta işe yaramadı çünkü ' ImportError: No module named PyQt4.QtCore' ve ' ImportError: No module named PyQt4.QtCore' gibi hata mesajları verdi .

Bunun nedeni PyQt4'ün düzgün yüklenmemiş olmasıdır. Kitaplıkları C: \ Python27 \ Lib konumunda tutuyordum, ancak PyQt4 için değil.

Aslında, http://www.riverbankcomputing.com/software/pyqt/download adresinden indirilmesi (kullandığınız doğru Python sürümüne dikkat edin) ve C: \ Python27'ye (benim durumum) yüklemesi yeterlidir. Bu kadar.

Şimdi komut dosyaları iyi çalışıyor, bu yüzden paylaşmak istiyorum. Qprinter kullanımıyla ilgili daha fazla seçenek için lütfen http://qt-project.org/doc/qt-4.8/qprinter.html#Orientation-enum'a bakın .

Yanıtlar:


159

Ayrıca pdfkit'i de kullanabilirsiniz :

Kullanım

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

Yüklemek

Mac os işletim sistemi: brew install Caskroom/cask/wkhtmltopdf

Debian / Ubuntu: apt-get install wkhtmltopdf

Pencereler: choco install wkhtmltopdf

MacOS / Ubuntu / diğer işletim sistemleri için resmi belgelere bakın: https://github.com/JazzCore/python-pdfkit/wiki/Installing-wkhtmltopdf


4
Bu harika, reportlab ile uğraşmaktan veya dönüştürmek için bir yazdırma sürücüsü kullanmaktan çok daha kolay. Çok teşekkürler.
Dowlers

@NorthCat html tablolarını pdfkit ile dönüştürme hakkında başka bir örnek verebilir misiniz?
Babel

1
Görünüşe göre windows pdfkit'i desteklemiyor. Bu doğru mu?
Kane Chew

2
Mükemmel !! Gömülü görüntüleri indirseniz bile, zahmet etmeyin! Yapmanız gerekecekapt-get install wkhtmltopdf
Tinmarino

4
pdfkit python olmayan wkhtmltopdf paketine bağlıdır ve bu da çalışan bir X sunucusu gerektirir. Yani bazı ortamlarda güzel olsa da, bu genellikle python'da işe yarayan bir cevap değildir.
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)

5
Url yerine dosya yolu sağlayabilir miyim?
Piyush S. Wanare

12
Bağımlılıkları bir sistem paketi yerine python paketleri olduğu için bu projeyi tercih edeceğimi düşünüyorum. Ocak 2018 itibariyle daha sık güncellemeler ve daha iyi belgelere sahip görünüyor.
stv

4
Yüklenecek çok şey var. Libpango'da durdum ve pdfkit'e gittim. Sistem genelinde wkhtmltopdf için kötüdür, ancak ileriye dönük yazdırmak için bazı sistem genelinde yüklemeler de gerekir.
visoft

1
Ben seçenek olmalıdır inanmazdı 'wb'değil 'w', çünkü pdfbir olduğunu bytesnesne.
Anatoly Scherbakov

1
benim için sadece ilk sayfayı indiriyor ve geri kalanını yok
sayıyor

24

Aşağıdaki gönderiler sayesinde ve kaç sayfa olursa olsun oluşturulan PDF üzerine yazdırılacak web sayfası bağlantı adresini ve şimdiki zamanı ekleyebiliyorum.

Python kullanarak Mevcut PDF'ye metin ekleyin

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

Komut dosyasını aşağıdaki gibi paylaşmak için:

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.'

Kodunuzu paylaştığınız için teşekkürler! Bunun yerel pdf dosyaları için çalışmasını sağlamak için herhangi bir tavsiye? Yoksa "file: ///" URL'sinin başına eklemek kadar kolay mı? Bu kitaplıklara pek aşina değilim ... teşekkürler
user2426679

@ user2426679, çevrimiçi PDF'yi yerel PDF dosyalarına dönüştürmek mi istiyorsunuz?
Mark K

Cevabınız için teşekkürler ... geç kaldığım için özür dilerim. Ona attığım şeyi halledebildiğinden wkhtmltopdf kullanmaya son verdim. Ama hdd'ime yerel olan bir pdf'i nasıl yükleyeceğimi soruyordum. Şerefe
user2426679

@ user2426679 üzgünüm seni hala anlamadım. belki de ben de Python'da acemi olduğum için. Python'da yerel PDF dosyalarını okumak mı istediniz?
Mark K

html5libXhtml2pdf tarafından kullanılan bazı sorunlar vardı . Bu çözüm sorunu çözdü: github.com/xhtml2pdf/xhtml2pdf/issues/318
Blairg23

14

işte iyi çalışan biri:

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_())

İlginç bir şekilde, web sayfası bağlantıları, oluşturulan PDF'de bağlantılar yerine metin olarak oluşturulur.
amergin

1
Bunun neden benim için boş pdf'ler oluşturduğunu bilen var mı?
bozon

11

İşte QT kullanarak basit bir çözüm. Bunu StackOverFlow'da farklı bir sorunun cevabının parçası olarak buldum. Windows'ta test ettim.

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!"

4

@ NorthCat yanıtını pdfkit kullanarak denedim.

Yüklenecek wkhtmltopdf gerekiyordu. Kurulum buradan indirilebilir. https://wkhtmltopdf.org/downloads.html

Yürütülebilir dosyayı yükleyin. Sonra aşağıdaki gibi wkhtmltopdf'nin nerede olduğunu belirtmek için bir satır yazın. ( Python PDFKIT kullanılarak pdf oluşturulamıyor'dan alıntı: "wkhtmltopdf yürütülebilir bulunamadı:"

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)

.deb'e tıkladıktan ve yazılım merkezine yükledikten sonra nereye gitti?
webNoob13

2

Bu çözüm PyQt5 sürüm 5.15.0 kullanarak benim için çalıştı

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_())

1

Selenyum ve krom kullanırsanız, çerezleri kendiniz yönetmenize gerek kalmaz ve chromium'un baskısından pdf olarak pdf sayfası oluşturabilirsiniz. Bunu gerçekleştirmek için bu projeye başvurabilirsiniz. https://github.com/maxvst/python-selenium-chrome-html-to-pdf-converter

değiştirilmiş taban> 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()

1
Öncelikle weasyprint kullanıyorum ama çerezleri desteklemiyor, siz default_url_fetcherçerezleri işlemek için kendiniz yazabilirsiniz ama daha sonra Ubuntu16'da kurarken sorun yaşıyorum. Wkhtmltopdf it destek çerez ayarını kullanıyorum ama tutarken -15 -11 gibi birçok OSERROR'a neden oldu bir sayfa.
Yuanmeng Xiao

Bay @ Yuanmeng Xiao'yu paylaştığınız için teşekkür ederiz.
Mark K
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.