【问题标题】:parsing a large html-file (local) - with Perl or PHP解析大型 html 文件(本地)- 使用 Perl 或 PHP
【发布时间】:2010-12-01 23:28:08
【问题描述】:

我有一个很大的文档 - 我需要解析它并只输出这部分:schule.php?schulnr=80287&lschb=

我该如何解析这些东西!?

<td>
    <A HREF="schule.php?schulnr=80287&lschb=" target="_blank">
        <center><img border=0 height=16 width=15 src="sh_info.gif"></center>
    </A>
</td>

很高兴收到您的来信

【问题讨论】:

  • 使用正则表达式,向黑暗领主低头。 codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html
  • 我正要说“什么样的傻瓜发布了一篇关于如何做这件坏事的博客文章......然后我注意到这是编码恐怖:) [对于未启动的编码恐怖博客所有者是 StackOverflow 的 2 位联合创始人之一,并且绝对是比我更好的程序员 :)]

标签: php perl text-parsing


【解决方案1】:

你应该使用像PHP Simple HTML DOM Parser这样的DOM解析器

// Create DOM from URL or file
$html = file_get_html('http://www.google.com/');

// Find all links 
foreach($html->find('a') as $element) 
       echo $element->href . '<br>';

【讨论】:

  • 嗨 Rfygyhn - 非常感谢。我会做的!我回来告诉你我所经历的。最好的问候
【解决方案2】:

在 Perl 中,我知道扫描 HTML 的最快和最好的方法是 HTML::PullParser。这是基于一个健壮的 HTML 解析器,而不是像 Perl 正则表达式(没有递归)这样的简单 FSA。

这更像是一个 SAX 过滤器,而不是一个 DOM。

use 5.010;
use constant NOT_FOUND => -1;
use strict;
use warnings;

use English qw<$OS_ERROR>;
use HTML::PullParser ();

my $pp 
    = HTML::PullParser->new(
      # your file or even a handle
      file        => 'my.html'
      # specifies that you want a tuple of tagname, attribute hash
    , start       => 'tag, attr' 
      # you only want to look at tags with tagname = 'a'
    , report_tags => [ 'a' ],
    ) 
    or die "$OS_ERROR"
    ;

my $anchor_url;
while ( defined( my $t = $pp->get_token )) { 
    next unless ref $t or $t->[0] ne 'a'; # this shouldn't happen, really
    my $href = $t->[1]->{href};
    if ( index( $href, 'schule.php?' ) > NOT_FOUND ) { 
        $anchor_url = $href;
        last;
    }
}

【讨论】:

    【解决方案3】:

    Rfvgyhn 所说的,但在 Perl 风格中,因为这是标签之一:使用 HTML::TreeBuilder

    另外,由于 RegEx几乎不是解析 XML/HTML 的一个好主意(有时它已经足够好,但有主要警告),请阅读 StackOverflow 的强制性和臭名昭著的帖子:

    RegEx match open tags except XHTML self-contained tags

    请注意,如果您的任务的全部内容实际上是“解析 HREF 链接”,并且您没有“”标签并且保证不会使用链接(例如 HREF="something" 子字符串)在任何其他情况下(例如,在 cmets 中,或作为文本,或将“HREF =”作为链接本身的一部分),它可能属于上面的“足够好”类别以用于正则表达式:

    my @lines = <>; # Replace with proper method of reading in your file
    my @hrefs = map { $_ =~ /href="([^"]+)"/gi; } @lines;
    

    【讨论】:

      【解决方案4】:

      你也可以这样做(不是 perl,而是更“可视化”):

      • 将文档加载到浏览器中, 如果可能的话
      • 安装 Firebug 扩展/插件
      • 安装 FirePath 扩展
      • 复制 + 粘贴此 XPath 表达式 进入标记为“XPpath:”的文本字段

        //a[包含(@href, "schule")]/@href

      • 点击“评估”按钮。

      还有一些工具可以在命令行上执行此操作,例如“xmllint”(适用于 unix)

      xmllint --html --xpath '//a[contains(@href, "schule")]/@href' myfile.php.or.html
      

      你可以从那里做进一步的处理。

      【讨论】:

        猜你喜欢
        • 2013-05-18
        • 2015-12-02
        • 1970-01-01
        • 2010-12-10
        • 1970-01-01
        • 1970-01-01
        • 2015-10-14
        • 2014-02-08
        • 2015-07-15
        相关资源
        最近更新 更多