如何使用Perl解析HTML网站?

时间:2010-04-30 23:16:17

标签: perl html-parsing

您能否就如何在Perl中解析HTML给我一些建议?我打算解析关键字(包括URL链接)并将它们保存到MySQL数据库。我使用的是Windows XP。

另外,我是否首先需要使用一些脱机资源管理器工具将一些网页下载到本地硬盘?如果我这样做,你能指点我一个好的下载工具吗?

4 个答案:

答案 0 :(得分:4)

您可以使用LWP检索需要解析的页面。解析HTML有很多方法。您可以使用正则表达式来查找链接和关键字(尽管通常不是一个好习惯),或者像HTML :: TokeParser或HTML :: TreeBuilder这样的模块。

答案 1 :(得分:2)

您可以使用众多HTML解析器模块中的一个。如果您熟悉jQuery,那么pQuery模块将是一个不错的选择,因为它将大多数易于使用的jQuery特性移植到Perl上进行HTML解析和抓取。

答案 2 :(得分:1)

HTTrack网站复印机/下载器的功能比任何可用的Perl库都多。

答案 3 :(得分:0)

要在本地遍历和保存整个网站,您可以使用wget -r -np http://localhost/manual/(wget在Windows上可用,可以单独使用,也可以在Cygwin / MinGW中使用)。 但是,如果您想要遍历抓取数据,Mojolicious可用于构建简单的并行Web爬网程序,非常依赖依赖项:

#!/usr/bin/env perl
use feature qw(say);
use strict;
use utf8;
use warnings qw(all);

use Mojo::UserAgent;

# FIFO queue
my @urls = (Mojo::URL->new('http://localhost/manual/'));

# User agent following up to 5 redirects
my $ua = Mojo::UserAgent->new(max_redirects => 5);

# Track accessed URLs
my %uniq;

my $active = 0;
Mojo::IOLoop->recurring(
    0 => sub {

        # Keep up to 4 parallel crawlers sharing the same user agent
        for ($active .. 4 - 1) {

            # Dequeue or halt if there are no active crawlers anymore
            return ($active or Mojo::IOLoop->stop) unless my $url = shift @urls;

            # Fetch non-blocking just by adding a callback and marking as active
            ++$active;
            $ua->get(
                $url => sub {
                    my (undef, $tx) = @_;

                    say "\n$url";
                    say $tx->res->dom->at('html title')->text;

                    # Extract and enqueue URLs
                    for my $e ($tx->res->dom('a[href]')->each) {
                        # Validate href attribute
                        my $link = Mojo::URL->new($e->{href});
                        next if 'Mojo::URL' ne ref $link;

                        # "normalize" link
                        $link = $link->to_abs($tx->req->url)->fragment(undef);
                        next unless $link->protocol =~ /^https?$/x;

                        # Access every link once
                        next if ++$uniq{$link->to_string} > 1;

                        # Don't visit other hosts
                        next if $link->host ne $url->host;

                        push @urls, $link;
                        say " -> $link";
                    }

                    # Deactivate
                    --$active;
                }
            );
        }
    }
);

# Start event loop if necessary
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;