【问题标题】:Printing PDF with selenium on Heroku (Django)在 Heroku (Django) 上使用 selenium 打印 PDF
【发布时间】:2022-01-20 10:09:45
【问题描述】:

我真的在为一个问题苦苦挣扎。我花了一个晚上试图解决它,进行了多项研究,但我找不到解决它的提示。

我的项目:通过 django 在 Heroku 应用程序上使用 selenium 和 chrome webdriver 将特定网页打印为 PDF。这个想法是,用户(我)在填写带有所选链接的网站上的表格后,会立即获得一个 pdf 文件。我的打印脚本在本地运行良好(我的 pdf 使用正确的参数下载),我的 heroku 应用运行良好(我设法从我的 Django 表单中检索到链接)。

这是我的索引方法,链接到我在模板中使用的表单。填写表格后,它会调用应该打印 pdf 的函数 (MyPdfSaver())。

def index(request):
submitbutton = request.POST.get("submit")

study_url = ''
test_value = ''
form = UserForm(request.POST or None)
if form.is_valid():
    study_url = form.cleaned_data.get("study_url")
    test_value = MyPdfSaver(study_url) #calling the function that prints as PDF. 

context = {
    'form': form,
    'study_url': study_url, #the link I want to print a PDF from
    'submitbutton': submitbutton,
    'test_value' : str(test_value) #just a test value 
}

return render(request, 'index.html', context)

这是我的 MyPdfSaver 函数(想法是通过此函数直接上传 pdf 并返回指向 pdf 的简单链接):

def MyPdfSaver(study_url):

# set webdriver and set chrome_options/settings
chrome_options = webdriver.ChromeOptions()
settings = {
    "recentDestinations": [{
        "id": "Save as PDF",
        "origin": "local",
        "account": "",
    }],
    "selectedDestinationId":
    "Save as PDF",
    "version":
    2,
    "isCssBackgroundEnabled":
    True
}
prefs = {
    'printing.print_preview_sticky_settings.appState':
    json.dumps(settings)
}
chrome_options.add_experimental_option('prefs', prefs)
chrome_options.add_argument('--kiosk-printing')
chrome_options.add_argument('--headless')
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--no-sandbox")

# set chrome bin location & driver (change paths to run locally)
chrome_options.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
driver = webdriver.Chrome(
    executable_path=os.environ.get("CHROMEDRIVER_PATH"),
    chrome_options=chrome_options)
driver.get(study_url)

# necessary for webpage to fully load
time.sleep(3)

html_source = driver.page_source
driver.execute_script('return window.print();') #is supposed to run the pdf printing

return str(type(html_source)) #just a try to see if it returns my driver well.

所以!几乎一切正常:链接被发送到我的 MyPdfSaver() 函数,MyPdfSaver() 运行 webdriver 没有任何错误并返回驱动程序内容(例如我的代码中的 html 代码)。但是这行代码似乎不起作用:

driver.execute_script('return window.print();') #I also tried without the "return"

虽然它应该在我的 Heroku 应用程序“中”下载 pdf,但我在任何地方都找不到该文件...我尝试了 heroku run bash 并运行了 ls -R,但它运行了一个新的测功机,所以它没有帮不了我。

所以主要问题是:我的driver.execute_script('return window.print();') 应该工作吗?如果是这样,下载的文件去哪里

如果您需要更多信息,请不要犹豫!

谢谢你:-)

PS:我看到 Selenium 4 提供了一个 driver.print() 函数,但我没有找到任何 Python 文档可以正确使用它,我认为问题会是一样的:我不知道我的文件在哪里当 selenium 下载它时进入我的 heroku 应用程序。

【问题讨论】:

  • 为什么不使用 wkhtmltopdf 而不是 selenium。
  • 我使用 selenium 和 execute_script("window.print;") 因为我想从中创建 pdf 的特定链接已经适合打印。我只想让我的应用程序模拟具有所需参数的打印框,而我不想占用整个页面。我将使用 wkhtmltopdf 进一步检查,但 selenium 在本地运行良好,我想依赖它:)

标签: python django selenium pdf heroku


【解决方案1】:

创建一个新的视图函数,

from django.http import FileResponse, Http404
    
def get_pdf(request, filename):
      try:
        return FileResponse(open('path_to_pdf/%s.pdf' % (filename), 'rb'), content_type='application/pdf')
      except FileNotFoundError:
        raise Http404()

并定义一个URL路径,

path('pdf/<str:filename>', get_pdf)

将上述文件链接返回给用户。

示例:app.com/pdf/file.pdf

【讨论】:

    猜你喜欢
    • 2019-07-08
    • 2022-07-08
    • 2019-06-02
    • 1970-01-01
    • 2022-08-16
    • 2019-10-18
    • 2020-01-28
    • 2018-01-28
    • 2021-07-20
    相关资源
    最近更新 更多