我试图弄清楚为什么某些东西不起作用是学习 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 中处理一个简单的循环以提高效率?