【问题标题】:Perl Regex to extract URLs from HTMLPerl 正则表达式从 HTML 中提取 URL
【发布时间】:2010-12-12 22:48:15
【问题描述】:

这应该是一个简单的正则表达式,但我似乎无法弄清楚。

有人可以提供一个 1-liner 来获取任意 HTML 输入字符串并使用 HTML 代码中的所有 Facebook URL(匹配 http://www.facebook.com)填充数组吗?

我不想使用任何 CPAN 模块,更喜欢简单的正则表达式 1-liner。

提前感谢您的帮助!

【问题讨论】:

  • 任意 HTML,嗯?它必须“在一条线上”,一条线?我希望它也不必放在 80 列中!并且没有 CPAN 模块。好吧,我可以做到,但你不希望我这样做,我敢肯定。您想要一个正确的答案,还是只偶尔有效的答案? cmets 或脚本段中的 URL 呢?被实体隐藏的东西呢?标签中间可以有cmets吗?

标签: regex perl


【解决方案1】:

解释why you shouldn't parse HTML using a regular expression的必填链接。

话虽如此,试试这个快速而肮脏的解决方案:

my $html = '<a href="http://www.facebook.com/">A link!</a>';
my @links = $html =~ /<a[^>]*\shref=['"](https?:\/\/www\.facebook\.com[^"']*)["']/gis;

【讨论】:

  • 这就是我一直在寻找的东西,我很欣赏为什么不使用正则表达式的解释。我想要一些又快又脏的东西,以后会回去清理。谢谢。
  • 原则上我反对告诉人们如何做到这一点,但无论如何 +1 用于使用否定字符类而不是 .*?(或者,更糟糕的是,只是 .*)。
【解决方案2】:

HTML::LinkExtor。尝试将正则表达式用于这些类型的任务是没有意义的。

您可以使用perldoc 实用程序阅读安装在您计算机上的 Perl 模块的文档。例如,perldoc HTML::LinkExtor。通常,模块文档以如何使用模块的示例开头。

这里是对文档中的一个示例的稍微现代一点的改编:

#!/usr/bin/env perl

use v5.20;
use warnings;

use feature 'signatures';
no warnings 'experimental::signatures';

use autouse Carp => qw( croak );

use HTML::LinkExtor qw();
use HTTP::Tiny qw();
use URI qw();

run( $ARGV[0] );

sub run ( $url ) {
    my @images;

    my $parser = HTML::LinkExtor->new(
        sub ( $tag, %attr ) {
            return unless $tag eq 'img';
            push @images, { %attr };
            return;
        }
    );

    my $response = HTTP::Tiny->new->get( $url, {
            data_callback => sub { $parser->parse($_[0]) }
        }
    );

    unless ( $response->{success} ) {
        croak sprintf('%d: %s', $response->{status}, $response->{reason});
    }

    my $base = $response->{url};

    for my $image ( @images ) {
        say URI->new_abs( $image->{src}, $base )->as_string;

    }
}

输出:

$ perl t.pl https://www.perl.com/
https://www.perl.com/images/site/perl-onion_20.png
https://www.perl.com/images/site/twitter_20.png
https://www.perl.com/images/site/rss_20.png
https://www.perl.com/images/site/github_light_20.png
https://www.perl.com/images/site/perl-camel.png
https://www.perl.com/images/site/perl-onion_20.png
https://www.perl.com/images/site/twitter_20.png
https://www.perl.com/images/site/rss_20.png
https://www.perl.com/images/site/github_light_20.png
https://i.creativecommons.org/l/by-nc/3.0/88x31.png

【讨论】:

  • 如果我们决定采用 HTML::LinkExtor 方向,您能否提供一些示例代码来说明其工作原理。谢谢!
  • 如果您只想说“查看文档”,为什么还要费心去帮助这个人
  • 代码过时了,所以我把它修好了,让它可以在 debian 10 上运行...gist.github.com/kanliot/dbb81b40e257ca315d6903f852547e18
【解决方案3】:

Russell C,你看过 Facebook 电影的开头吗,马克·扎克伯格使用 Perl 自动从大学 Facebook 中提取所有照片(然后将它们发布到网上)。我当时想“我就是这样做的!我也会使用 Perl!” (除了我可能需要几天的时间来锻炼,而不是 2 分钟)。无论如何,我会使用模块 WWW::Mechanize 来提取链接(或照片):

use strict; use WWW::Mechanize; open (OUT, ">out.txt"); my $url="http://www.facebook.com"; my $mech=WWW::Mechanize->new(); $mech->get($url); my @a = $mech->links; print OUT "\n", $a[$_]->url for (0..$#a);

但是,这不会让您登录到您的 Facebook 页面,它只会将您带到登录屏幕。我会使用 HTTP::Cookies 登录。为此,请参阅文档。开个玩笑,随便问问。天哪,苹果馅饼在燃烧!

【讨论】:

    【解决方案4】:

    也许这可以帮助你:

    if ($input =~ /(http:\/\/www\.facebook\.com\/\S+)/) { push(@urls, $1); }
    

    【讨论】:

    • 不评论正则表达式,为什么不把整个 html 页面吞进去,然后做类似@urls = $html =~ /([regex])/gm 或者/gs 之类的事情,我总是忘记。尽管如此,您还是可以一口气完成所有比赛。
    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多