如何在WWW :: Mechanize中处理一个简单的循环以提高效率

时间:2012-04-08 23:10:58

标签: perl parsing loops text-parsing www-mechanize

我试图找出为什么某些东西不起作用是学习Perl的一种非常好的方法。 有时你会发现一个bug,希望能够得到一个解决方法。

我认为Perl是一种学习方式的好方法 - 通过第一种方法和现实世界问题的试验。

目前我正在做一个简单的网站抓取工具,从中提取信息 一些法国餐馆的页面 - 更准确地说是巴黎地区的餐馆

我在巴黎寻找餐馆,我想拿出他们拥有的菜单......这只是一种通过脚本获得有用的东西的方法。我的女朋友对新食谱和菜单很感兴趣,所以我试着从世界上最好的厨房得到一些意见;-)

更新,因为我们通过Google的帮助和互动来做这个小脚本我试试 防止违反Google的服务条款。所以我认为我们需要在代码中使用Sleep函数。 scrpt必须每十个结果入睡。所以我们保持秩序井然并尝试保存谷歌服务器,只使用谷歌的性能。你说什么! - 注意我是初学者.. oalders建议看看WWW :: Mechanize :: Cached -well这是一个很好的胜利 - 使用www :: mechanize :: cached非常有帮助 - 它有助于保存资源,因为它会缓存结果并使我们无法一遍又一遍地进行搜索。

想要什么 * *我正在使用一些关键字餐厅 paris 菜单

使用这些关键字,我尝试进行谷歌搜索。 注意 - 我认为有必要首先获取餐馆的页面,然后解析链接“菜单”的所有结果页面 这只是一个例子,表明我们首先得到了餐馆的结果页面 - 可能与搜索条件:“paris”& “餐厅”。下一步是获取我们获得的页面 - 例如以下页面。我们必须用关键字“menu”解析它们 然后我需要拥有页面上包含的所有文本..-请参阅此处的一些示例

http://www.bouillon-chartier.com/index.php/en/menu http://www.letrois.com/menu.php

我在这里有第一步 - 一个在这里:这是一个执行谷歌搜索的脚本

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中处理一个简单的循环以提高效率

但是比上面提到的脚本更好,就是这样(见下文)这样做 - 我想这项工作必须两次折叠 - 如上所述......因为我们需要先得到结果 - 餐馆的页面 - 可能与搜索条款 巴黎&amp;餐厅我们其次采取下一步采取我们得到的页面 - 例如以下的。我们必须使用关键字“menu”解析它们 - 我想我们可以使用下面这个脚本做得更好......

然后我需要拥有页面上包含的所有文字..-

-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 "";
}

嗯,我认为我首先要得到餐馆所有网址的清单 - 然后我必须解析它们。因此 - 对于这两个折叠的任务,我必须重新设计一下脚本。

  • 收集网址是第一步
  • 解析它们 - 使用特殊目标“菜单”是第二步
  • 并且第三个将是最困难的 - 我需要记录菜单 - 带有标识符 - 餐厅的名称,

所以喜欢这个

1。 http://www.bouillon-chartier.com/index.php/en/menu

餐厅名称: bouillon-chartier.com 菜单: coq au vin,lorem ipsum

2。 http://www.letrois.com/menu.php

餐厅名称 letrois 菜单:薄饼,pommes frites,lorem ipsum

所有菜单都应存储在某个数据库中,或者至少应该以csv的形式存储。 但那将是最容易的部分。 目前我试图弄清楚我们如何将第一步(获取网址)与第二步分开....即解析菜单的目标网址 - 并打开菜单并解析此...

我们可以像这样指定问题:如何在WWW :: Mechanize中处理一个简单的循环以提高效率?

0 个答案:

没有答案