WWW::Mechanize::Chrome调用new方法报797行拼接错误如何解决
问题场景
使用WWW::Mechanize::Chrome模块开发PDF生成功能,核心初始化代码如下:
use Log::Log4perl qw(:easy); use WWW::Mechanize::Chrome; my $chrome; sub chrome { Log::Log4perl->easy_init($ERROR); my $mech = WWW::Mechanize::Chrome->new( headless => 1, 'disable-gpu' => 1, launch_exe => 'chromium-browser', );
调用new方法初始化实例时程序抛出错误,排查后确认报错触发位置为模块源码第797行的字符串拼接逻辑,相关现场截图如下:
问题根因
这是Perl典型的未初始化值参与字符串拼接的运行时错误,触发链路非常明确:
- 模块启动Chrome/Chromium进程后,默认会读取进程的标准输出,通过正则匹配提取DevTools协议的WebSocket连接地址
- 旧版本
WWW::Mechanize::Chrome的匹配正则没有适配Chromium 110+版本的启动日志格式;另外如果是snap源安装的沙箱版Chromium,沙箱权限会拦截模块读取进程输出的操作,两种情况都会导致提取到的WebSocket地址变量值为undef - 代码执行到第797行拼接连接字符串时,未定义的变量直接参与拼接,就抛出了对应的错误。
修复方案
按优先级从高到低尝试以下方案即可:
- 升级
WWW::Mechanize::Chrome到最新版本,新版已经适配了新版Chromium的日志格式,执行如下命令升级:
cpanm WWW::Mechanize::Chrome
- 如果升级后仍报错,把初始化参数里的
headless => 1改成headless => 'old',强制浏览器使用旧版headless模式启动,输出格式和旧版本完全兼容,修改后的初始化配置参考:
my $mech = WWW::Mechanize::Chrome->new( headless => 'old', 'disable-gpu' => 1, launch_exe => 'chromium-browser', );
- 如果是snap安装的Chromium触发的沙箱权限问题,可以额外加
no_sandbox => 1参数关闭沙箱限制,或者直接卸载snap版Chromium,改用apt官方源安装的常规版本:
my $mech = WWW::Mechanize::Chrome->new( headless => 'old', 'disable-gpu' => 1, launch_exe => 'chromium-browser', no_sandbox => 1, );
- 以上方案都不生效的话,可以绕过模块自动启动浏览器、自动提取连接地址的逻辑,手动启动Chromium开启远程调试端口,再让模块直接连接已启动的实例:
- 先手动执行命令启动浏览器:
chromium-browser --headless=new --disable-gpu --no-sandbox --remote-debugging-port=9222- 初始化模块时直接指定调试地址,不需要模块自行启动进程:
my $mech = WWW::Mechanize::Chrome->new( launch_exe => '', ws_url => 'ws://127.0.0.1:9222/devtools/browser', );
内容的提问来源于stack exchange,提问作者muhana
相关产品推荐
相关产品推荐

