Python을 사용하여 웹 페이지를 PDF로 변환하는 방법


95

Python을 사용하여 웹 페이지를 로컬 파일 PDF로 인쇄하는 솔루션을 찾고있었습니다. 좋은 해결책 중 하나는 Qt ( https://bharatikunal.wordpress.com/2010/01/ )를 사용하는 것 입니다.

PyQt4 설치에 문제가있어서 처음에는 ' ImportError: No module named PyQt4.QtCore', ' ' 와 같은 오류 메시지를 표시했기 때문에 처음에는 작동하지 않았습니다 ImportError: No module named PyQt4.QtCore.

PyQt4가 제대로 설치되지 않았기 때문입니다. C : \ Python27 \ Lib에 라이브러리가 있지만 PyQt4 용이 아닙니다.

실제로 http://www.riverbankcomputing.com/software/pyqt/download 에서 다운로드하고 (사용중인 올바른 Python 버전을 확인) C : \ Python27 (제 경우)에 설치하면됩니다. 그게 다야.

이제 스크립트가 잘 실행되므로 공유하고 싶습니다. Qprinter 사용에 대한 추가 옵션은 http://qt-project.org/doc/qt-4.8/qprinter.html#Orientation-enum을 참조하십시오 .

답변:


157

pdfkit 을 사용할 수도 있습니다 .

용법

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

설치

맥 OS: brew install Caskroom/cask/wkhtmltopdf

Debian / Ubuntu : apt-get install wkhtmltopdf

Windows : choco install wkhtmltopdf

MacOS / Ubuntu / 기타 OS에 대한 공식 문서 참조 : https://github.com/JazzCore/python-pdfkit/wiki/Installing-wkhtmltopdf


4
이것은 reportlab을 엉망으로 만들거나 인쇄 드라이브를 사용하여 변환하는 것보다 굉장하고 쉽습니다. 정말 고마워.
Dowlers

@NorthCat은 pdfkit으로 html 테이블을 변환하는 것에 대한 또 다른 예를 줄 수 있습니까?
Babel

1
Windows가 pdfkit을 지원하지 않는 것 같습니다. 사실인가요?
Kane Chew

2
완벽합니다! 임베드 된 이미지를 다운로드하더라도 사용하지 마십시오! 당신은해야합니다apt-get install wkhtmltopdf
Tinmarino

4
pdfkit은 파이썬이 아닌 패키지 wkhtmltopdf에 의존하며, 차례로 실행중인 X 서버가 필요합니다. 따라서 일부 환경에서는 좋지만 일반적으로 파이썬에서 작동하는 대답은 아닙니다.
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 대신 파일 경로를 제공 할 수 있습니까?
Piyush S. Wanare

12
종속성이 시스템 패키지가 아닌 파이썬 패키지이기 때문에이 프로젝트를 선호 할 것이라고 생각합니다. 2018 년 1 월 현재 더 빈번한 업데이트와 더 나은 문서가있는 것 같습니다.
stv

4
설치할 것이 너무 많습니다. 나는 libpango에서 멈춰서 pdfkit으로 갔다. 시스템 전체 wkhtmltopdf에는 좋지 않지만 weasyprint에는 시스템 전체 설치가 필요합니다.
visoft

1
나는 옵션이 있어야한다고 생각 것 'wb',하지 'w'때문에, pdfA는 bytes객체입니다.
Anatoly Scherbakov

1
나를 위해 그것은 첫 페이지 만 다운로드하고 나머지는 무시합니다
Fábio

24

아래 게시물 덕분에 웹 페이지 링크 주소를 추가하여 인쇄 할 수 있고 생성 된 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 파일에 대한 조언이 있습니까? 아니면 URL 앞에 "file : ///"을 붙이는 것만 큼 쉬운가요? 이 라이브러리에 대해 잘
모르겠습니다

@ user2426679, 온라인 PDF를 로컬 PDF 파일로 변환한다는 뜻입니까?
Mark K

답장을 보내 주셔서 감사합니다 ... 지각해서 죄송합니다. 내가 던지는 것을 처리 할 수 ​​있었기 때문에 wkhtmltopdf를 사용하게되었습니다. 하지만 내 HDD에 로컬 인 pdf를로드하는 방법을 묻고있었습니다. 건배
user2426679 dec.

@ user2426679 미안하지만 여전히 당신을 얻지 못합니다. 나도 파이썬 초보자이기 때문일 수 있습니다. 파이썬으로 로컬 PDF 파일을 읽으려고 했습니까?
Mark K

html5libxhtml2pdf에서 사용하는에 몇 가지 문제가 있습니다 . 이 솔루션은 문제를 해결했습니다 : github.com/xhtml2pdf/xhtml2pdf/issues/318
Blairg23

14

다음은 잘 작동하는 것입니다.

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의 링크가 아닌 텍스트로 생성됩니다.
amergin

1
왜 이것이 나를 위해 빈 PDF를 생성하는지 아는 사람이 있습니까?
boson

11

다음은 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!"

4

pdfkit을 사용하여 @NorthCat 답변을 시도했습니다.

wkhtmltopdf를 설치해야합니다. 설치는 여기에서 다운로드 할 수 있습니다. https://wkhtmltopdf.org/downloads.html

실행 파일을 설치하십시오. 그런 다음 아래와 같이 wkhtmltopdf가 어디에 있는지 나타내는 줄을 작성하십시오. ( Ca n't create pdf using python PDFKIT Error : "No wkhtmltopdf executable found :"에서 참조)

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)

2

이 솔루션은 PyQt5 버전 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_())

1

셀레늄과 크롬을 사용하는 경우 쿠키를 직접 관리 할 필요가 없으며 크롬 인쇄물에서 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 = "/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
먼저 weasyprint를 사용하지만 쿠키 default_url_fetcher를 처리하기 위해 직접 작성할 수 있어도 쿠키를 지원하지 않지만 나중에 Ubuntu16에 설치할 때 문제가 발생합니다. 그런 다음 wkhtmltopdf를 사용하여 쿠키 설정을 지원하지만 처리 할 때 -15-11과 같은 많은 OSERROR 일부 페이지.
Yuanmeng Xiao

@Yuanmeng Xiao 씨를 공유해 주셔서 감사합니다.
Mark K
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.