J'ai essayé toutes les solutions que j'ai pu trouver sur Internet pour pouvoir imprimer une page ouverte dans Selenium en Python. Cependant, alors que la fenêtre contextuelle d'impression apparaît, après une ou deux secondes, elle disparaît, sans PDF enregistré.
Voici le code essayé. Basé sur le code ici - https://stackoverflow.com/a/43752129/3973491
Codage sur un Mac avec Mojave 10.14.5.
from selenium import webdriver import json chrome_options = webdriver.ChromeOptions() settings = { "appState": { "recentDestinations": [{ "id": "Save as PDF", "origin": "local", "account": "", }], "selectedDestinationId": "Save as PDF", "version": 2 } } prefs = {'printing.print_preview_sticky_settings': json.dumps(settings)} chrome_options.add_experimental_option('prefs', prefs) chrome_options.add_argument('--kiosk-printing') CHROMEDRIVER_PATH = '/usr/local/bin/chromedriver' driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=CHROMEDRIVER_PATH) driver.get("https://google.com") driver.execute_script('window.print();') driver.quit()
$chromedriver --v ChromeDriver 75.0.3770.90 (a6dcaf7e3ec6f70a194cc25e8149475c6590e025-refs/branch-heads/3770@{#1003})
Tout conseil ou solution sur ce qui peut être fait pour imprimer la page html ouverte dans un PDF. J'ai passé des heures à essayer de faire ce travail. Merci!
Mise à jour le 11/07/2019:
Ma question a été identifiée comme un doublon, mais a) l'autre question semble utiliser du code javascript, et b) la réponse ne résout pas le problème soulevé dans cette question - cela peut être lié à des versions logicielles plus récentes. La version Chrome utilisée est la version 75.0.3770.100 (version officielle) (64 bits), et chromedriver est ChromeDriver 75.0.3770.90. Sur Mac OS Mojave. Le script s'exécute sur Python 3.7.3.
Mise à jour le 11/07/2019:
Le code a été remplacé par
from selenium import webdriver from selenium.webdriver.support.select import Select from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import TimeoutException from selenium.webdriver.chrome.options import Options from selenium.common.exceptions import WebDriverException import time import json options = Options() appState = { "recentDestinations": [ { "id": "Save as PDF", "origin": "local" } ], "selectedDestinationId": "Save as PDF", "version": 2 } profile = {'printing.print_preview_sticky_settings.appState': json.dumps(appState)} # profile = {'printing.print_preview_sticky_settings.appState':json.dumps(appState),'savefile.default_directory':downloadPath} options.add_experimental_option('prefs', profile) options.add_argument('--kiosk-printing') CHROMEDRIVER_PATH = '/usr/local/bin/chromedriver' driver = webdriver.Chrome(options=options, executable_path=CHROMEDRIVER_PATH) driver.implicitly_wait(5) driver.get(url) driver.execute_script('window.print();')
Et maintenant, rien ne se passe. Chrome se lance, charge l'URL, la boîte de dialogue d'impression apparaît mais rien ne semble se produire - rien dans la file d'attente par défaut de l'imprimante, et pas de pdf non plus - J'ai même recherché les fichiers PDF en recherchant "Fichiers récents" sur Mac.
4 Réponses :
La réponse ici , a fonctionné lorsque je n'avais aucune autre configuration d'imprimante dans mon système d'exploitation. Mais quand j'avais une autre imprimante par défaut, cela ne fonctionnait pas.
Je ne comprends pas comment, mais faire de petits changements de cette façon semble fonctionner.
from selenium import webdriver import json chrome_options = webdriver.ChromeOptions() settings = { "recentDestinations": [{ "id": "Save as PDF", "origin": "local", "account": "", }], "selectedDestinationId": "Save as PDF", "version": 2 } prefs = {'printing.print_preview_sticky_settings.appState': json.dumps(settings)} chrome_options.add_experimental_option('prefs', prefs) chrome_options.add_argument('--kiosk-printing') CHROMEDRIVER_PATH = '/usr/local/bin/chromedriver' driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=CHROMEDRIVER_PATH) driver.get("https://google.com") driver.execute_script('window.print();') driver.quit()
Merci @Kamal. Cette approche fonctionne en effet mais elle s'imprime sur la dernière imprimante utilisée. Je viens de faire quelques recherches et je me demande si cups-pdf installé en tant qu'imprimante et si cups-pdf est la dernière imprimante utilisée peut aboutir au résultat souhaité - imprimer en pdf en utilisant python.
Désolé, je n'ai pas pu tester ma solution sous Linux, cela a fonctionné sous Windows 10 pour moi.
je l'ai. J'y travaillerai un peu plus et je verrai si je peux trouver quelque chose.
J'ai travaillé sur Linux pour moi. Ce serait bien si nous pouvions contrôler l'emplacement de téléchargement, cependant.
La solution n'est pas très bonne, mais vous pouvez prendre une capture d'écran et la convertir en pdf par Pillow ...
from selenium import webdriver from io import BytesIO from PIL import Image driver = webdriver.Chrome(executable_path='path to your driver') driver.get('your url here') img = Image.open(BytesIO(driver.find_element_by_tag_name('body').screenshot_as_png)) img.save('filename.pdf', "PDF", quality=100)
Merci pour votre réponse. Le problème avec cette approche est qu'elle ne fonctionne pas pour les pages Web de plusieurs pages. Seule une partie des informations est capturée. Mais c'est une bonne solution pour les pages courtes et n'implique pas de popups.
qu'entendez-vous par pages Web multi-pages ?
ce qui signifie les pages Web qui doivent faire défiler pour voir la page Web complète et une fois imprimées au format PDF, elles tiennent sur 3-4 feuilles de papier.
vous pouvez utiliser ce code: stackoverflow.com/a/57608276/10661593 , et à la fin enregistrer au format pdf. Ps je n'ai pas compris un peu, désolé. Voulez-vous adapter la page entière sur 1 feuille lors de l'impression? ou comment
donc ce que je veux idéalement pouvoir faire - c'est imprimer une page au format pdf. sur un Mac, lorsque vous faites cela, le PDF généré peut s'exécuter sur plusieurs pages - en supposant que le PDF est créé pour une impression au format Lettre ou A4. si je rétrécis beaucoup la page et que je prends une capture d'écran qui ne sert pas le but. bien que, maintenant je comprends que Selenium ne contrôle pas les boîtes de dialogue du navigateur, et ne peut donc pas imprimer la page au format PDF. apparemment, le marionnettiste ou le pyppétiste en python peuvent le faire mais je ne sais pas encore comment utiliser ce logiciel. le lien que vous avez partagé semble parler de capture d'écran et non de pdf ...
vous pouvez enregistrer une capture d'écran au format pdf, pourquoi pas?
Je peux. Mais la page que je souhaitais enregistrer se heurte à de nombreux écrans de défilement vertical. Et ainsi cela deviendrait multiple et bas de page, puis convertir chaque capture d'écran en PDF, puis combiner les PDF. Je viens de penser à cela en fonction de votre commentaire. Cela semble encore assez kludgy, et j'espérais qu'il y aura une meilleure solution. Pyppeteer pourrait me permettre de le faire en Python semble-t-il, mais je ne sais pas comment m'en servir. :(
Je pense que cela résoudrait mon problème. miyakogi.github.io/pyppeteer/_modules/pyppeteer/… . Cependant, je ne connais pas async et attend, et j'ai besoin de les apprendre avant d'essayer d'utiliser Pyppeteer. Difficile de croire que Selenium ne pouvait pas le faire comme je l'avais en quelque sorte appris ...
Je ne dirai pas que je suis bouleversé. :) Selenium est gratuit et merci à l'équipe pour ça! C'est juste que j'étais certain que cela pouvait être fait et je pensais que je ne connaissais pas la bonne syntaxe ou les bonnes options pour activer l'impression PDF dans Selenium. Utiliser des kludges ne semble pas être la bonne chose. Il finira par se briser.
Voici la solution que j'utilise avec Windows:
Téléchargez d'abord ChromeDriver ici: http://chromedriver.chromium.org/downloads et installez Selenium
Ensuite, exécutez ce code (basé sur la réponse acceptée, légèrement modifiée pour fonctionner sous Windows):
import json from selenium import webdriver chrome_options = webdriver.ChromeOptions() settings = {"recentDestinations": [{"id": "Save as PDF", "origin": "local", "account": ""}], "selectedDestinationId": "Save as PDF", "version": 2} prefs = {'printing.print_preview_sticky_settings.appState': json.dumps(settings)} chrome_options.add_experimental_option('prefs', prefs) chrome_options.add_argument('--kiosk-printing') browser = webdriver.Chrome(r"chromedriver.exe", options=chrome_options) browser.get("https://google.com/") browser.execute_script('window.print();') browser.close()
Il s'agit d'une révision si minime ("Selon la documentation de sélénium, spécifiez les emplacements des pilotes Windows (par exemple, chromedriver.exe
) plutôt que les emplacements des pilotes Linux lors de l'exécution sous Windows") qu'il devrait simplement s'agir d'un commentaire sur la réponse acceptée. De plus, il semble que vous ayez simplement minifié la réponse acceptée pour rendre le code différent.
@RobHall Les commentaires sont parfois effacés après des années; aussi parfois, il est difficile d'extraire des informations de plusieurs commentaires, donc cette réponse. J'ai correctement cité la source ("sur la base de la réponse acceptée"); le diable est vraiment dans les détails, j'ai passé beaucoup de temps à essayer et à échouer avant que cela fonctionne enfin, donc mon objectif était vraiment de mettre un code prêt à l'emploi pour Windows comme réponse.
Vous pouvez utiliser le code suivant pour imprimer des PDF au format A5 avec le CSS d'arrière-plan activé:
import os from selenium import webdriver from selenium.webdriver.common.keys import Keys import json import time chrome_options = webdriver.ChromeOptions() settings = { "recentDestinations": [{ "id": "Save as PDF", "origin": "local", "account": "" }], "selectedDestinationId": "Save as PDF", "version": 2, "isHeaderFooterEnabled": False, "mediaSize": { "height_microns": 210000, "name": "ISO_A5", "width_microns": 148000, "custom_display_name": "A5" }, "customMargins": {}, "marginsType": 2, "scaling": 175, "scalingType": 3, "scalingTypePdf": 3, "isCssBackgroundEnabled": True } mobile_emulation = { "deviceName": "Nexus 5" } chrome_options.add_experimental_option("mobileEmulation", mobile_emulation) chrome_options.add_argument('--enable-print-browser') #chrome_options.add_argument('--headless') prefs = { 'printing.print_preview_sticky_settings.appState': json.dumps(settings), 'savefile.default_directory': '<path>' } chrome_options.add_argument('--kiosk-printing') chrome_options.add_experimental_option('prefs', prefs) for dirpath, dirnames, filenames in os.walk('<source path>'): for fileName in filenames: print(fileName) driver = webdriver.Chrome("./chromedriver", options=chrome_options) driver.get(f'file://{os.path.join(dirpath, fileName)}') time.sleep(7) driver.execute_script('window.print();') driver.close()
aucun PDF enregistré , où avez-vous vérifié? Il doit être enregistré dans votre dossier Téléchargements utilisateur.
@Kamal - J'ai essayé à nouveau, et j'ai remarqué que Chrome tirait une impression réelle sur mon imprimante par défaut, mais je n'étais pas au même endroit, donc je n'ai pas remarqué ce qui s'était réellement passé. supprimé la file d'attente d'impression des nombreuses fois où j'avais essayé d'imprimer au format pdf / apparu que rien ne s'est passé. donc je soupçonne que l'option "Enregistrer au format PDF" n'est pas sélectionnée et je ne sais pas comment la sélectionner.
Veuillez vous référer à cette réponse . Dans votre code, vous appelez
webdriver.Chrome(options=options..
, mais la syntaxe correcte estwebdriver.Chrome(chrome_options=options..
Et d'une certaine manière, avecwebdriver.ChromeOptions
print fonctionne plus rapidement qu'avecwebdriver.chrome.options.Options
, donc je vous suggère d'essayer cela.Copie possible de Set Selenium ChromeDriver UserPreferences to Save as PDF
@Kamal - Merci pour vos commentaires. J'ai juste essayé ça aussi. a changé le code en chrome_options = webdriver.ChromeOptions (). Et en effet, webdriver.ChromeOptions semble fonctionner plus rapidement, mais même cette option déclenche une impression vers l'imprimante par défaut et non vers le PDF: (Toujours à la recherche de conseils sur la façon de procéder - si ce n'est pas avec Selenium, je me demande si c'est possible avec une autre bibliothèque. Cependant, la page que je dois atteindre est après une procédure de connexion.
Le code d'une autre question fonctionne pour moi, alors pouvez-vous mettre à jour votre question avec le dernier code que vous avez essayé?
Mise à jour de la question avec le dernier code que j'ai utilisé. Cette fois, rien ne semble aller nulle part même si la boîte de dialogue d'impression semble se lancer. La boîte de dialogue d'impression est trop rapide et ne peut pas lire quelle imprimante ou si l'option PDF est sélectionnée. Intrigué. Merci @Kamal de rester engagé et de m'avoir aidé à résoudre ce problème.