【问题标题】:Selenium Chrome save as pdf change download folderSelenium Chrome 另存为 pdf 更改下载文件夹
【发布时间】:2019-07-01 21:31:15
【问题描述】:

我想将网站下载为 pdf 文件,它工作正常,但它应该将文件下载到特定路径,而不是将文件下载到我的默认下载目录。

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();')

顺便说一句,有人想用特定名称保护文件吗?

【问题讨论】:

  • 由于 selenium 使用页面标题作为 PDF 文件名,因此只需将页面标题更改为您希望在打印之前为 PDF 指定的名称。 driver.execute_script('document.title="{}";'.format(YOUR_PDF_NAME)); driver.execute_script('window.print();')

标签: python selenium web-scraping


【解决方案1】:

download.default_directory 设置仅适用于下载的内容。 Chrome 以不同的方式处理保存在页面上的文件。要更改页面打印输出的默认文件夹,只需设置 savefile.default_directory 值即可。

因此,为自定义位置打印到 pdf 的完整示例:

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();')

【讨论】:

  • 我这样做了,但仍然得到打印预览对话框,使用 chrome 81
【解决方案2】:

另一种解决方法。只需按原样保存文件,然后根据需要移动和重命名即可。

下面代码的思路:查看下载目录下每个(pdf)文件的创建时间,并与现在的时间进行比较。如果时间增量小于某个值(比如 15 秒),大概这是正确的文件,请将文件移动/重命名到您需要的位置。

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)

注意:这只是一个例子。你需要考虑你的所有行为。为了使代码稳定,您可能需要添加一些异常处理。最好将此附加代码移动到函数中。以此类推。

【讨论】:

    【解决方案3】:

    download.default_directory 不能添加到 appState,而是添加到 "prefs"add_experimental_option

    喜欢:

    chrome_options.add_experimental_option("prefs", {
        'download.default_directory': 'C:\\Users\\Oli\\Google Drive',
        'download.directory_upgrade': True
    })
    

    但在你的情况下它没有帮助,因为这个选项设置了“文件->另存为”的位置,你需要“打印->另存为”

    作为一种解决方法,您可以为 Chrome 使用 --print-to-pdf 参数(无需运行 Chrome Webdriver,但 Chrome 本身处于无头模式)

    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)
    

    当它在静默模式下运行时要小心,如果没有创建文件(例如,如果没有这样的目录,或者没有 C:\Users 的管理员权限,或者没有这样的网页),则不会出现警告消息。

    您可以随时在命令行 (cmd) 中进行测试,例如:

    start chrome --headless --print-to-pdf="C:\\temp\\1.pdf" http://example.com
    

    【讨论】:

    • 感谢您的解释。是否可以像 selenium 浏览器那样在没有 selenium 的情况下控制 Chrome?因为我得到的 PDF 文件的链接是一个临时链接,我无法打开新的 chrome 浏览器来下载这个 pdf 文件。
    • 不,您需要 Selenium,因为您需要在保存之前执行一些操作。因此,作为一种解决方法,您可以使用驱动器上的文件。再看一个答案中的示例。
    猜你喜欢
    • 2020-08-20
    • 2021-04-30
    • 2018-05-02
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 2013-07-23
    • 1970-01-01
    • 2019-05-28
    相关资源
    最近更新 更多