Je souhaite télécharger un site Web sous forme de fichier pdf, cela fonctionne bien, mais il devrait télécharger le fichier vers un chemin spécifique, au lieu de cela, il ne fait que télécharger le fichier dans mon répertoire de téléchargement par défaut.
import json from selenium import webdriver appState = { "recentDestinations": [ { "id": "Save as PDF", "origin": "local" } ], "selectedDestinationId": "Save as PDF", "version": 2, 'download.default_directory': 'C:\\Users\\Oli\\Google Drive', "download.directory_upgrade": True } profile = {'printing.print_preview_sticky_settings.appState': json.dumps(appState)} chrome_options = webdriver.ChromeOptions() chrome_options.add_experimental_option('prefs', profile) chrome_options.add_argument('--kiosk-printing') driver = webdriver.Chrome(chrome_options=chrome_options) driver.get('https://www.google.com/') driver.execute_script('window.print();')
Au fait, quelqu'un a eu l'idée de sécuriser le fichier avec un nom spécifique?
3 Réponses :
download.default_directory
pourrait être ajouté non pas à appState
mais à "prefs"
de add_experimental_option
comme:
start chrome --headless --print-to-pdf="C:\\temp\\1.pdf" http://example.com
mais dans votre cas, cela n'aiderait pas, car cette option définit l'emplacement pour 'fichier -> enregistrer sous', et vous avez besoin de 'imprimer -> enregistrer sous '
Pour contourner ce problème, vous pouvez utiliser l'argument --print-to-pdf
pour Chrome (pas besoin d'exécuter Chrome Webdriver, mais Chrome lui-même en mode sans tête) p >
import os path_to_file = 'C:\\Users\\Oli\\Google Drive\\' name_of_file = '1.pdf' page_to_open = 'http://example.com' command_to_run = 'start chrome --headless --print-to-pdf="{0}{1}" {2}'.format(path_to_file, name_of_file, page_to_open) print('launch:'+command_to_run) os.popen(command_to_run)
Faites attention car il fonctionne en mode silencieux, pas de message d'avertissement si le fichier n'est pas créé (par exemple si aucun répertoire de ce type, ou aucun droit d'administrateur sur C: \ Users, ou aucun page Web).
Et vous pouvez toujours tester directement dans la ligne de commande (cmd) comme:
chrome_options.add_experimental_option("prefs", { 'download.default_directory': 'C:\\Users\\Oli\\Google Drive', 'download.directory_upgrade': True })
Merci pour ton explication. Est-il possible de contrôler Chrome sans sélénium comme le navigateur sélénium? Parce que le lien que j'obtiens vers le fichier PDF est un lien temporaire et que je ne peux pas ouvrir un nouveau navigateur Chrome pour télécharger ce fichier pdf.
Non, vous avez besoin de Selenium car vous avez besoin de certaines actions avant la sauvegarde. Pour contourner le problème, vous pouvez travailler avec les fichiers de votre lecteur. Regardez l'exemple dans une autre réponse.
Encore une solution de contournement. Enregistrez simplement le fichier tel quel, puis déplacez-le et renommez-le si nécessaire.
Idée du code ci-dessous: vérifiez l'heure de création de chaque fichier (pdf) dans le répertoire de téléchargement, et comparez avec l'heure actuelle. Si le delta de temps est inférieur à une certaine valeur (disons 15 secondes), il s'agit probablement du bon fichier, déplacez / renommez le fichier dont vous avez besoin.
import os import time import json from selenium import webdriver appState = { "recentDestinations": [ { "id": "Save as PDF", "origin": "local" } ], "selectedDestinationId": "Save as PDF", "version": 2 } profile = {'printing.print_preview_sticky_settings.appState': json.dumps(appState)} download_path = r'C:\Users\Oli\Downloads' # Path where browser save files new_path = r'C:\Users\Oli\Google Drive' # Path where to move file chrome_options = webdriver.ChromeOptions() chrome_options.add_experimental_option('prefs', profile) chrome_options.add_argument('--kiosk-printing') driver = webdriver.Chrome(chrome_options=chrome_options) driver.get('http://example.com/') driver.execute_script('window.print();') new_filename = 'new_name.pdf' # Set the name of file timestamp_now = time.time() # time now # Now go through the files in download directory for (dirpath, dirnames, filenames) in os.walk(download_path): for filename in filenames: if filename.lower().endswith(('.pdf')): full_path = os.path.join(download_path, filename) timestamp_file = os.path.getmtime(full_path) # time of file creation # if time delta is less than 15 seconds move this file if (timestamp_now - timestamp_file) < 15: full_new_path = os.path.join(new_path, new_filename) os.rename(full_path, full_new_path) print(full_path+' is moved to '+full_new_path)
Remarque: c'est juste un exemple. Vous devez penser à toutes vos actions. Pour rendre le code stable, vous devrez peut-être ajouter une gestion des exceptions. Mieux vaut déplacer ce code supplémentaire vers une fonction. Et ainsi de suite.
Le paramètre download.default_directory
concerne uniquement le contenu téléchargé. Chrome traite différemment les fichiers enregistrés sur la page. Pour changer le dossier par défaut pour une impression de la page, définissez simplement la valeur savefile.default_directory
à la place.
Donc l'exemple complet pour imprimer en pdf pour un emplacement personnalisé:
import json from selenium import webdriver appState = { "recentDestinations": [ { "id": "Save as PDF", "origin": "local", "account": "" } ], "selectedDestinationId": "Save as PDF", "version": 2 } profile = {'printing.print_preview_sticky_settings.appState': json.dumps(appState), 'savefile.default_directory': 'path/to/dir/'} chrome_options = webdriver.ChromeOptions() chrome_options.add_experimental_option('prefs', profile) chrome_options.add_argument('--kiosk-printing') driver = webdriver.Chrome(options=chrome_options) driver.get(url) driver.execute_script('window.print();')
Je fais cela mais j'obtiens toujours la boîte de dialogue d'aperçu avant impression, en utilisant Chrome 81