python subprocess – google-chrome headless – self-signed certificate – screenshot

huangapple go评论63阅读模式
英文:

python subprocess - google-chrome headless - self-signed certificate - screenshot

问题

从您提供的信息来看,问题可能与在对象方法中运行subprocess时的环境权限有关。在对象方法中,可能会受到不同的环境限制,导致某些功能不起作用。

为了解决这个问题,您可以尝试以下几点:

  1. 确保在对象方法中使用相同的用户权限和环境变量。您可以在对象方法中添加一些代码,以确保使用相同的环境设置,尤其是在涉及文件路径和权限的情况下。

  2. 在对象方法中添加适当的错误处理和日志记录,以便更好地了解问题所在。这将有助于识别哪些部分可能失败,并提供更多的上下文信息。

  3. 尝试在对象方法中运行其他简单的subprocess命令,以查看是否存在相同的问题。这可以帮助缩小问题的范围,确定是否仅与特定的subprocess调用有关。

  4. 考虑使用其他方法来截取网页内容,例如使用Python的requests库来下载网页内容,而不是依赖于subprocess来运行浏览器。

通过执行上述步骤,您可以更好地诊断和解决问题,以确保在对象方法中正确运行您的subprocess调用。

英文:

When opening a django shell:

python manage.py shell

and typing in:

import subprocess
command = [
  f'google-chrome',
  '--headless=new',
  f'--screenshot=/home/user/tmp/screen.png',
  f'--window-size=800,1700',
  '--no-first-run',
  '--allow-http-screen-capture',
  '--force-device-scale-factor=1',
  '--ignore-certificate-errors',
  '--ignore-urlfetcher-cert-requests',
  '--disable-test-root-certs',
  '--allow-running-insecure-content',
  '--hide-scrollbars',
  '--allow-insecure-localhost',
  '--disable-system-font-check',
  '--disable-gpu',
  '--disable-extensions',
  '--disable-dev-shm-usage',
  '--disable-software-rasterizer',
  '--disable-notifications',
  '--user-data-dir=/tmp/chromium-home',
  '/home/user/tmp/screen.html',
]
subprocess.run(command, **{})

The console output is the following:

[32873:32901:0419/083534.872076:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/user/0/bus: Permission denied
[32873:32901:0419/083534.884135:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/user/0/bus: Permission denied
[32873:32901:0419/083534.970536:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/user/0/bus: Permission denied
[32873:32901:0419/083534.970630:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/user/0/bus: Permission denied

(process:32873): dconf-CRITICAL **: 08:35:35.289: unable to create directory '/run/user/0/dconf': Permission denied.  dconf will not work properly.

(process:32873): dconf-CRITICAL **: 08:35:35.314: unable to create directory '/run/user/0/dconf': Permission denied.  dconf will not work properly.

(process:32873): dconf-CRITICAL **: 08:35:35.350: unable to create directory '/run/user/0/dconf': Permission denied.  dconf will not work properly.
[32873:32899:0419/083537.631303:ERROR:cert_verify_proc_builtin.cc(679)] CertVerifyProcBuiltin for 127.0.0.1 failed:
----- Certificate i=0 (<snip>) -----
ERROR: No matching issuer found


[32873:32897:0419/083537.639022:ERROR:cert_verify_proc_builtin.cc(679)] CertVerifyProcBuiltin for 127.0.0.1 failed:
----- Certificate i=0 (<snip>) -----
ERROR: No matching issuer found


572051 bytes written to file /home/user/tmp/screen.png
CompletedProcess(args=['google-chrome', '--headless=new', '--screenshot=/home/user/tmp/screen.png', '--window-size=800, 1700', '--no-first-run', '--allow-http-screen-capture', '--force-device-scale-factor=1', '--ignore-certificate-errors', '--ignore-urlfetcher-cert-requests', '--disable-test-root-certs', '--allow-running-insecure-content', '--hide-scrollbars', '--allow-insecure-localhost', '--disable-system-font-check', '--disable-gpu', '--disable-extensions', '--disable-dev-shm-usage', '--disable-software-rasterizer', '--disable-notifications', '--user-data-dir=/tmp/chromium-home', '/home/user/tmp/screen.html'], returncode=0)

Looks worrying, but the screen.png file is properly "screenshotted".
We can even see the certificate errors, which are mentioned but apparently ignored as requested in the subprocess call.

By the way, the bash calling works too, i.e., :

$ google-chrome --headless=new --screenshot=/home/user/tmp/screen.png --window-size=800,1700 --no-first-run --allow-http-screen-capture --force-device-scale-factor=1 --ignore-certificate-errors --ignore-urlfetcher-cert-requests --disable-test-root-certs --allow-running-insecure-content --hide-scrollbars --allow-insecure-localhost --disable-system-font-check --disable-gpu --disable-extensions --disable-dev-shm-usage --disable-software-rasterizer --disable-notifications --user-data-dir=/tmp/chromium-home /home/user/tmp/screen.html

works too.

Google chrome version is google-chrome-unstable.x86_64 114.0.5696.0-1 on Rocky Linux 9. The problem described below is the same with the stable version.

Now I would like to ru the above subprocess call from within a model function, like so:

class MyModel(models.Model):
    <snip>

    def render(self):
        import subprocess
        commands = [
            f'google-chrome',
            '--headless=new',
            f'--screenshot=/home/user/tmp/screen.png',
            f'--window-size=800,1700',
            '--no-first-run',
            '--allow-http-screen-capture',
            '--force-device-scale-factor=1',
            '--ignore-certificate-errors',
            '--ignore-urlfetcher-cert-requests',
            '--disable-test-root-certs',
            '--allow-running-insecure-content',
            '--hide-scrollbars',
            '--allow-insecure-localhost',
            '--disable-system-font-check',
            '--disable-gpu',
            '--disable-extensions',
            '--disable-dev-shm-usage',
            '--disable-software-rasterizer',
            '--disable-notifications',
            '--user-data-dir=/tmp/chromium-home',
            '/home/user/tmp/screen.html',
        ]
        subprocess.run()

The command line output is:

[33681:33708:0419/085053.463656:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/user/0/bus: Permission denied
[33681:33708:0419/085053.464599:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/user/0/bus: Permission denied
[33681:33708:0419/085053.589267:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/user/0/bus: Permission denied
[33681:33708:0419/085053.589373:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/user/0/bus: Permission denied

(process:33681): dconf-CRITICAL **: 08:50:53.761: unable to create directory '/run/user/0/dconf': Permission denied.  dconf will not work properly.

(process:33681): dconf-CRITICAL **: 08:50:53.768: unable to create directory '/run/user/0/dconf': Permission denied.  dconf will not work properly.

(process:33681): dconf-CRITICAL **: 08:50:53.821: unable to create directory '/run/user/0/dconf': Permission denied.  dconf will not work properly.
8899 bytes written to file /home/user/tmp/screen.png

Errors are similar, but the SSL certificate errors are not there.

Given that the contents of the HTML file are (or very similar, the file is dynamically generated):

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, shrink-to-fit=no">
<style>
*{
    box-sizing:border-box;
    margin:0;
    padding:0;
}
html{
    -webkit-print-color-adjust:exact;
}
.upload{
    overflow:hidden;
    height:1600px;
    width:800px;
    display:block;
}
.upload > img{
    display:block;
    width:100%;
}
</style>
</head>
<body>
<div class="upload">
<img src="https://docs.celeryq.dev/en/stable/_static/celery_512.png"><br>
<img src="https://127.0.0.1:1310/m/u/befe5aa9-690b-410d-a3bc-7ba9a75c382a.webp" alt="This is a test">
</div>
</body>
</html>

I am guessing subnprocess is somehow skipping? ignoring? discarding? the image calls made by the headless browser?

In a word:

  • works from bash command line
  • works from "normal" python shell
  • does not work from an object method

I am at a loss -- any clues?

答案1

得分: 1

如果你原谅我打岔一下,我是个白痴 python subprocess – google-chrome headless – self-signed certificate – screenshot
将答案贴出以备后人,因为网络是永恒的,也是为了提醒自己。 python subprocess – google-chrome headless – self-signed certificate – screenshot

答案位于HTML文件的动态生成中:

错误版本:

def render(self):
     html_render = '<some /><markup />'
     with open(temp_html_full_path, 'w') as f:
         f.write(html_render)
         command = []
         subprocess.run(command, **{})

正常版本:

def render(self):
     html_render = '<some /><markup />'
     with open(temp_html_full_path, 'w') as f:
         f.write(html_render)
     command = []
     subprocess.run(command, **{})

请注意 subprocess 调用是在 with 文件写入块内/外部完成的。

英文:

If you'll excuse my French, I am an idiot python subprocess – google-chrome headless – self-signed certificate – screenshot
Will post the answer for posterity and since the internet is forever, as a reminder for myself. python subprocess – google-chrome headless – self-signed certificate – screenshot

the answer was in the dynamic generation of the HTML file:

Broken version:

def render(self):
     html_render = &#39;&lt;some /&gt;&lt;markup /&gt;&#39;
     with open(temp_html_full_path, &#39;w&#39;) as f:
         f.write(html_render)
         command = []
         subprocess.run(command, **{})

Working version:

def render(self):
     html_render = &#39;&lt;some /&gt;&lt;markup /&gt;&#39;
     with open(temp_html_full_path, &#39;w&#39;) as f:
         f.write(html_render)
         command = []
         subprocess.run(command, **{})

Notice how the subprocess call is made inside/outside the with file writing block.

huangapple
  • 本文由 发表于 2023年4月19日 16:55:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76052552.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定