You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么Web::Scraper无法提取script标签内的文本内容?

问题原因
  • Web::Scraper底层依赖HTML::TreeBuilder解析HTML,HTML::TreeBuilder默认会将<script>、<style>等标签的内联内容识别为CDATA节点,而非普通文本节点
  • Web::Scraper内置的TEXT抽取过滤器默认只会提取普通文本节点内容,会自动忽略CDATA节点,因此最终返回空值
正确处理方法

有两种常用方案,不需要提前修改标签名:

方案1:自定义回调直接提取CDATA内容

直接在process规则中传入回调,从script元素节点中直接读取CDATA内容,示例修改如下:

our $scraper = scraper {
  # 替换原来的TEXT过滤器为自定义回调
  process 'script', "script" => sub {
    my $elem = shift;
    # 提取CDATA内容并去除首尾空白
    my $content = $elem->content_array_ref->[0] // '';
    $content =~ s/^\s+|\s+$//g;
    return $content;
  };
  process 'p', "p" => 'TEXT';
  process 'other', "other" => 'TEXT';
};

修改后运行即可正常拿到test script的输出。

方案2:修改HTML::TreeBuilder默认解析规则

在解析前修改底层解析器的配置,取消将script标签内容识别为CDATA的默认规则,后续直接用TEXT过滤器即可正常提取:

use Web::Scraper;
use Data::Dumper;
use HTML::TreeBuilder;

# 修改默认解析配置,清空CDATA标签列表
my $builder = HTML::TreeBuilder->new;
$builder->cdata_sections([]);

my $html = q|
<html>
  <head>
    <title>test html</title>
  </head>
  <body>
    <script>
      test script
    </script>

    <p>
      p test
    </p>

    <other>
      other test
    </other>

  </body>
</html>
|;

our $scraper = scraper {
  process 'script', "script" => 'TEXT';
  process 'p', "p" => 'TEXT';
  process 'other', "other" => 'TEXT';
};

# 传入自定义的解析器实例执行抓取
my $data = $scraper->scrape( $html, undef, { tree_builder => $builder } );
say Dumper $data;

两种方案都可以稳定获取script标签内的内联内容,方案1不需要修改全局解析配置,更推荐在多场景抓取的代码中使用。

内容的提问来源于stack exchange,提问作者w.k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 14:09:03