【问题标题】:extract all links from a HTML page, exclude links from a specific table从 HTML 页面中提取所有链接,从特定表中排除链接
【发布时间】:2023-03-30 20:35:01
【问题描述】:

我对 Perl/HTML 还是很陌生。这是我要对WWW::MechanizeHTML::TreeBuilder 做的事情:

对于 Wikipedia 上的每个化学元素页面,我需要提取指向 wiki 上其他化学元素页面的所有超链接,并以这种格式打印每个唯一对:

Atomic_Number1 (Chemical Element Title1) -> Atomic_Number2 (Chemical Element Title2)

唯一的问题是每个化学元素的页面(页面右上角)都有一个迷你元素周期表。因此,这个微小的元素周期表只会使每个元素的结果都相同。我在从该表中提取页面中的所有链接时遇到问题。

[注意:为了便于调试,我只查看了$elem == 6(Carbon)(@line 42)。]


这是我的代码:

#!/usr/bin/perl -w

use strict;
use warnings;
use WWW::Mechanize;
use HTML::TreeBuilder;
my $mech = WWW::Mechanize->new( autocheck => 1 );

$mech = WWW::Mechanize->new();

my $table_url = "http://en.wikipedia.org/wiki/Periodic_table";

$mech->agent('Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-us) /
              AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1   /
              Safari/533.17.8');

$mech->get($table_url);

my $tree = HTML::TreeBuilder->new_from_content($mech->content);
my %elem_set;
my $atomic_num;

## obtain a hash array of elements and corresponding titles and links
foreach my $td ($tree->look_down(_tag => 'td')) {

  # If there's no <a> in this <td>, then skip it:
  my $a = $td->look_down(_tag => 'a') or next;

  my $tdText = $td->as_text;
  my $aText  = $a->as_text;

  if($tdText =~ m/^(\d+)\S+$/){
    if($1 <= 114){  #only investigate up to 114th element
      $atomic_num = $1;
    }
    $elem_set{$atomic_num} = [$a->attr('title'), $a->attr('href')];
  }
}

## In each element's page. look for links to other elements in the set
foreach my $elem (keys %elem_set) {
  if($elem == 6){
    # reconstruct element url to ensure only fetch pages in English
    my $elem_url = "http://en.wikipedia.org" . $elem_set{$elem}[1];
    $mech->get($elem_url);

    #####################################################################
    ### need help here to exclude links from that mini periodic table ###
    #####################################################################

    my @target_links = $mech->links();
    for my $link ( @target_links ) {
      if( $link->url =~ m/^\/(wiki)\/.+$/ && $link->text =~ m/^\w+$/ ){
        printf("%s, %s\n", $link->text, $link->url);
      }
    }

  }
}

【问题讨论】:

    标签: html perl perl-module www-mechanize


    【解决方案1】:

    在找到链接之前,使用 WWW::Mechanize 的 update_html 方法删除该表。这个方法可以让你对$mech-&gt;content中的源代码做任何你想做的事情。

    【讨论】:

    • 谢谢!但事实证明,删除 wiki 页面上的表格并不是一种非常准确,更不用说高效的方法来实现我想要做的事情,因为每个化学元素的 wiki 页面上的表格在其标签中都有不同的内容。所以很难为所有页面推广一个表格删除功能。实际上,我最终使用 HTML::TreeBuilder 来查找

      标记中的链接(因为我要查找的链接很可能出现在段落中)。它产生了更准确的结果并且运行速度非常快。
    猜你喜欢
    • 1970-01-01
    • 2021-11-30
    • 2011-06-04
    • 2014-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-24
    相关资源
    最近更新 更多