0

我试图弄清楚为什么某些东西不起作用是学习 Perl 的好方法。有时您会发现一个错误,并希望能够找到解决方法。

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

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

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

更新:由于我们在 Google 的帮助和互动下编写了这个小脚本,因此我试图防止违反 Google 的 TOS。所以我认为我们需要在代码中有一个睡眠功能。脚本必须每十个结果就入睡。所以我们把事情整理好,尽量保存谷歌服务器,只使用一点谷歌的性能。你说什么!- 注意我是初学者.. oalders 建议看看 WWW::Mechanize::Cached - 这显然是一个伟大的胜利 - 使用 www::mechanize::cached 非常有帮助 - 它有助于保存资源,因为它会缓存结果并避免我们一遍又一遍地进行搜索。

*想要什么 * 我在寻找一些关键字餐厅巴黎菜单

使用这些关键字,我尝试进行谷歌搜索。注意- 我认为有必要首先获取餐馆的页面,然后解析链接“菜单”的所有结果页面这只是一个示例,表明我们首先获得了餐馆的结果页面 - 可能使用搜索词:“巴黎”和“餐厅”。下一步是获取我们获得的页面 - 例如以下页面。我们必须用关键字“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 中处理一个简单的循环以提高效率

但比上面提到的脚本更好,它会是这种方式(见下文) - 我想这项工作必须是两个折叠 - 如上所述......因为我们首先需要有结果页面餐厅 - 可能使用搜索词巴黎和餐厅,我们接下来会执行下一步以获取我们获得的页面 - 例如以下页面。我们必须用关键字“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 菜单:薄饼、炸薯条、lorem ipsum

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

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

4

0 回答 0