1

例として:

.txtから入力をロードします。

ベンジャミン、シュヴライン、ドイツ、1912年、M、ホワイト

簡潔にするためにここに投稿しないコードをいくつか実行し、リンクにアクセスします。

https://familysearch.org/pal:/MM9.1.1/K3BN-LLJ

  1. そのページから複数のものを削りたい。以下のコードでは、1つだけ実行します。
  2. また、出力.txtで、各項目を。で区切るようにします。
  3. そして、出力の前に入力を付けてほしい。

コードで次のパッケージを使用しています。

use strict;
use warnings;
use WWW::Mechanize::Firefox;
use Data::Dumper;
use LWP::UserAgent;
use JSON;
use CGI qw/escape/;
use HTML::DOM;

関連するコードは次のとおりです。

my $ua = LWP::UserAgent->new;
open(my $o, '>', 'out2.txt') or die "Can't open output file: $!";
# Here is the url, although in practice, it is scraped itself using different code
my $url = 'https://familysearch.org/pal:/MM9.1.1/K3BN-LLJ'; 
print "My URL is <$url>\n";  
my $request = HTTP::Request->new(GET => $url);
  $request->push_header('Content-Type' => 'application/json');
  my $response = $ua->request($request);
 die "Error ".$response->code if !$response->is_success;
 my $dom_tree = new HTML::DOM;
 $dom_tree->write($response->content);
 $dom_tree->close;
  my $str = $dom_tree->getElementsByTagName('table')->[0]->getElementsByTagName("td")->[10]->as_text();
 print $str;
print $o $str;

(そのリンクからの)必要な出力は次のようなものです。

ベンジャミン、シュヴライン、ドイツ、1912年、M、ホワイト、クイーンズ、ニューヨーク、既婚、同じ場所、頭など...

(その出力セクションのどれだけがスクレイプ可能ですか?)

リンク内のリンクを取得する方法についてのヘルプをいただければ幸いです。

4

3 に答える 3

2

HTML::TreeBuilder::XPathこれは、HTMLにアクセスするために使用してかなり簡単に行われます。このプログラムは、ラベルをキーとして使用してデータのハッシュを作成するため、必要な情報を抽出できます。カンマまたは空白を含むフィールドはすべて引用符で囲みます。

X-Copyrightこの方法でデータを抽出するこのWebサイトの許可があるかどうかはわかりませんが、HTTP応答のこのヘッダーに注意を向ける必要があります。このアプローチは、明らかにプログラムによるアクセスのヘッダーに該当します。

X-著作権:著作権警告FamilySearch APIを介してアクセスできるデータは、著作権によって保護されています。許可なく、このデータにプログラムでアクセス、再フォーマット、または再ルーティングすることは禁止されています。ファミリーサーチは、そのような無許可の使用は、その複製、派生、および配布の権利の侵害であると見なします。詳細については、devnet(at)familysearch.orgにお問い合わせください。

あなたからのメールを期待していますか?私はあなたの最初のメールに返信しましたが、それ以来聞いていません。

use strict;
use warnings;

use URI;
use LWP;
use HTML::TreeBuilder::XPath;

my $url = URI->new('https://familysearch.org/pal:/MM9.1.1/K3BN-LLJ');

my $ua = LWP::UserAgent->new;
my $resp = $ua->get($url);
die $resp->status_line unless $resp->is_success;

my $tree = HTML::TreeBuilder::XPath->new_from_content($resp->decoded_content);
my @results = $tree->findnodes('//table[@class="result-data"]//tr[@class="result-item"]');
my %data;
for my $item (@results) {
  my ($key, $val) = map $_->as_trimmed_text, $item->content_list;
  $key =~ s/:$//;
  $data{$key} = $val;
}

my $record = join ',', map { local $_ = $data{$_}; /[,\s]/ ? qq<"$_"> : $_ }
  'name', 'birthplace', 'estimated birth year', 'gender', 'race (standardized)',
  'event place', 'marital status', 'residence in 1935',
  'relationship to head of household (standardized)';

print $record, "\n";

出力

"Benjamin Schuvlein",Germany,1912,Male,White,"Assembly District 2, Queens, New York City, Queens, New York, United States",Married,"Same Place",Head
于 2013-02-13T16:24:44.480 に答える
2

これを試して

use LWP::Simple;
use LWP::UserAgent;
use HTML::TableExtract;

$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;
$ua = LWP::UserAgent->new;
$ua->agent("Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.91 Safari/537.11");
$req = HTTP::Request->new(GET => "https://familysearch.org/pal:/MM9.1.1/K3BN-LLJ");
$res = $ua->request($req);
$content = $res->content;
#$content = get("https://familysearch.org/pal:/MM9.1.1/K3BN-LLJ") or die "Couldn't get it! $!";
$te = HTML::TableExtract->new( attribs => { 'class' => 'result-data' } );
# $te = HTML::TableExtract->new( );
$te->parse($content);
$table = $te->first_table_found;
# print $content; exit;
# $te->tables_dump(1);
#print Dumper($te);
#print Dumper($table);
print $table->cell(4,0) . ' = ' . $table->cell(4,1), "\n"; exit;

どちらが出力されますか

イベント会場: = Assembly District 2, Queens, New York City, Queens, New York, United States

このヘッダーにも気付きました:

X-著作権: 著作権に関する警告 FamilySearch API を通じてアクセスできるデータは、著作権によって保護されています。このデータのプログラムによるアクセス、再フォーマット、または再ルーティングは、許可なく禁止されています。ファミリーサーチは、そのような無許可の使用は、その複製、派生、配布の権利の侵害であると考えています。詳細については、devnet (at) familysearch.org にお問い合わせください。

http://metacpan.org/pod/HTML::Element#SYNOPSISも参照してください。

于 2013-02-12T02:37:16.617 に答える
0

私はあなたの質問に答えたと思いました。

問題は、LWP で Web ページを取得しようとしていることです。すでに WWW::Mechanize::Firefox を持っているのに、なぜそれをしようとするのですか?

これを試しましたか?

さらに分析するために、各リンクを取得して保存します。少し変更すると、DOM ツリーが「取得」されます。申し訳ありませんが、私はこのページにアクセスできません。うまくいくことを願っています。

my $i=1;
for my $link (@links) {
  print Dumper $link->url;
  print Dumper $link->text;
  my $tempfile = './$i.html';$i++;
  $mech->get( $link, ':content_file' => $tempfile, synchronize => 1 );
  my $dom_tree = $mech->document();
  my $str = $dom_tree->getElementsByTagName('table')->[0]->getElementsByTagName("td")->[9]->as_text();

 }

編集: regexp を使用してページのコンテンツを処理します (皆さん: Perl を使用して何かを行うには、常に複数の方法があることを覚えておいてください!. 動作し、簡単です...)

このコマンドで試してみました:

wget -nd ' https://familysearch.org/pal:/MM9.1.1/K3BN-LLJ ' -O 1.html|猫 1.html|1.pl

use Data::Dumper;
use strict;
use warnings;

local $/=undef;
my $html = <>;#read from file
#$html = $mech->content( format => 'html' );# read data from mech object
my $data = {};
my $current_label = "not_defined";
while ($html =~ s!(<td[^>]*>.*?</td>)!!is){ # process each TD
    my $td = $1;
    print "td: $td\n";
    my $td_val = $td;
    $td_val =~ s!<[^>]*>!!gis;
    $td_val =~ s!\s+! !gs;
    $td_val =~ s!(\A\s+|\s+\z)!!gs;
    if      ($td =~ m!result-label!){ #primitive state machine, store the current label
        print "current_label: $current_label\n";
        $current_label = $td_val;
    } elsif ($td =~ m!result-value!){ #add each data to current label
        push(@{$data->{$current_label}},$td_val);

    } else {
        warn "found something else: $td\n";
    }
}
#process it using a white lists of known entries (son,race, etc).Delete from the result if you find it on white list, die if you find something new.
#multi type
foreach my $type (qw(son wife daughter head)){
    process_multi($type,$data->{$type});
    delete($data->{$type});
}
#simple type
foreach my $type (qw(birthplace age)){
    process_simple($type,$data->{$type});
    delete($data->{$type});
}

die "Unknown label!".Dumper($data) if scalar(keys %{$data})>0;

出力:

      'line number:' => [
                          '28'
                        ],
      'estimated birth year:' => [
                                   '1912'
                                 ],
      'head' => [
                  'Benjamin Schuvlein',
                  'M',
                  '28',
                  'Germany'
                ],
于 2013-02-11T15:09:50.283 に答える