何かがうまくいかない理由を理解しようとしていますが、これは Perl を学ぶのに非常に良い方法です。バグを見つけて、うまくいけば回避策を得ることができる場合があります。
Perl は学習方法としては良い方法だと思います。つまり、最初のアプローチを行い、実際の問題を試してみることです。
現時点では、フランスのレストランのいくつかのページから情報を抽出する少し単純なサイトクローラーを実行しています-より正確には、パリエリアのレストランから
パリのレストランを探して、そこにあるメニューを取り出したいのですが... これは、スクリプトを使用して何か役立つものを取得する方法にすぎません。私のガールフレンドは新しいレシピとメニューに興味があるので、世界最高のキッチンから情報を得ようとしています ;-)
更新:この小さなスクリプトは、Google との協力とやり取りによって作成されるため、Google の TOS に違反しないように努めています。したがって、コードにスリープ機能が必要だと思います。スクリプトは、10 件の結果ごとにスリープ状態になる必要があります。そのため、物事を整理して、Google サーバーを節約し、Google のパフォーマンスを少しだけ使用しようとします。あなたは何を言っていますか!- 私は初心者であることに注意してください.. oalders は WWW::Mechanize::Cached を見てみることをお勧めします。結果をキャッシュし、検索を何度も行う必要がなくなるため、リソースを保存します。
*欲しいもの: * 私はいくつかのキーワードレストラン、パリ、メニューを探しています
これらのキーワードを使用して、Google 検索を試みます。注- 最初にレストランのページを取得し、その後、リンク「メニュー」のすべての結果ページを解析する必要があると思います。これは、最初にレストランの結果ページを取得したことを示す単なる例です。おそらく「パリ」と「レストラン」という検索語で。次のステップは、取得したページを取得することです。たとえば、次のページです。キーワード「メニュー」でそれらを解析する必要があり、ページに含まれるすべてのテキストを取得する必要があります..-ここでいくつかの例を参照してください
http://www.bouillon-chartier.com/index.php/en/menu http://www.letrois.com/menu.php
ここに最初のステップがあります - ここに 1 つ: これは Google 検索を実行するためのスクリプトです
use WWW::Mechanize;
use 5.10.0;
use strict;
use warnings;
my $mech = new WWW::Mechanize;
my $option = $ARGV[$#ARGV];
# we may customize the google search by editing this url (always end it with "q=" though)
my $google = 'http://www.google.co.uk/search?q=';
my @dork = ("inurl:", "restaurant", "paris","menu");
#declare necessary variables
my $max = 0;
my $link;
my $sc = scalar(@dork);
#start the main loop, one itineration for every google search
for my $i ( 0 .. $sc ) {
#loop until the maximum number of results chosen isn't reached
while ( $max <= $option ) {
$mech->get( $google . $dork[$i] . "&start=" . $max );
#get all the google results
foreach $link ( $mech->links() ) {
my $google_url = $link->url;
if ( $google_url !~ /^\// && $google_url !~ /google/ ) {
say $google_url;
}
}
$max += 10;
}
}
これは良い方法ですが、非常に最初のアプローチにすぎません。難しいタスクが残っています。
パリの大都市圏のすべてのレストランを取得する方法と、すべてのメニューを保存する方法!? それは少しトリッキーですが、私は確信しています。Perl を学ぶための素晴らしい教訓です。さて、私はここから始めます: なるほど - タスクは次のように綴ることができます: WWW::Mechanize で単純なループを処理してより効率的にする方法
しかし、上記のスクリプトよりも優れているのは、この方法 (以下を参照) です。これを行うには、上記のように、この作業を 2 つに折りたたむ必要があると思います。レストラン - おそらく検索用語 paris & restaurant を使用して、取得したページを取得するための次のステップを実行します。たとえば、次のページです。「メニュー」というキーワードを使用してそれらを解析する必要があります。以下のスクリプトを使用すると、もう少しうまく処理できると思います...
そして、ページに含まれるすべてのテキストが必要です..-
-http://www.bouillon-chartier.com/index.php/en/menu -http://www.letrois.com/menu.php
#call the mechanize object, with autocheck switched off
#so we don't get error when bad/malformed url is requested
my $mech = WWW::Mechanize->new(
autocheck => 0
);
my %comments;
my %links;
my @comment;
my $target = "http://google.com";
#store the first target url as not checked
$links{$target} = 0;
#initiate the search
my $url = &get_url();
#start the main loop
while ( $url ne "" ) {
#get the target url
$mech->get($url);
#search the source for any html comments
my $res = $mech->content;
@comment = $res =~ /<!--[^>]*-->/g;
#store comments in 'comments' hash and output it on the screen, if there are any found
$comments{$url} = "@comment" and say "\n$url \n---------------->\n $comments{$url}" if $#comment >= 0;
#loop through all the links that are on the current page (including only urls that are contained in html anchor)
foreach my $link ( $mech->links() ) {
$link = $link->url();
#exclude some irrelevant stuff, such as javascript functions, or external links
#you might want to add checking domain name, to ensure relevant links aren't excluded
if ( $link !~ /^(#|mailto:|(f|ht)tp(s)?\:|www\.|javascript:)/ ) {
#check whether the link has leading slash so we can build properly the whole url
$link = $link =~ /^\// ? $target . $link : $target . "/" . $link;
#store it into our hash of links to be searched, unless it's already present
$links{$link} = 0 unless $links{$link};
}
}
#indicate we have searched this url and start over
$links{$url} = 1;
$url = &get_url();
}
sub get_url {
my $key, my $value;
#loop through the links hash and return next target url, unless it's already been searched
#if all urls have been searched return empty, ending the main loop
while ( ( $key, $value ) = each(%links) ) {
return $key if $value == 0;
}
return "";
}
まず、レストランのすべての URL のリストを取得する必要があると思います。その後、それらを解析する必要があります。したがって、この 2 つ折りのタスクでは、スクリプトを少し再設計する必要があります。
- URLの収集は最初のステップです
- それらを解析する - 特別なターゲット「メニュー」を使用して、2番目のステップです
- 3つ目は最も難しいものです - メニューを説明する必要があります - 識別子 - レストランの名前
このように
1. http://www.bouillon-chartier.com/index.php/en/menu
レストランの名前: bouillon-chartier.com メニュー: コック・オ・ヴァン、ロレム・イプサム
2. http://www.letrois.com/menu.php
レストランの名前letrois メニュー:クレープ、ポムフリット、lorem ipsum
すべてのメニューは何らかのデータベースに保存するか、少なくとも csv として提供する必要があります。しかし、それは最も簡単な部分です。現時点では、ステップ 1 (URL の取得) を 2 番目のステップから分離する方法を理解しようとしています....つまり、メニューのターゲット URL を解析し、メニューを開いてこれを解析します... .
問題を次のように特定できます: WWW::Mechanize で単純なループをより効率的に処理するには?