是否有像Perl的LWP for Ruby这样的模块?

时间:2011-11-25 21:07:25

标签: ruby perl rubygems

在Perl中有一个LWP module

  

libwww-perl集合是一组Perl模块,它为万维网提供简单而一致的应用程序编程接口(API)。该库的主要重点是提供允许您编写WWW客户端的类和函数。该库还包含更常用的模块,甚至包含可帮助您实现简单HTTP服务器的类。

Ruby有类似的模块(gem)吗?

更新

以下是我从特定网站中提取网址的功能示例。

use LWP::UserAgent;
use HTML::TreeBuilder 3;
use HTML::TokeParser;

sub get_gallery_urls {
    my $url = shift;

    my $ua = LWP::UserAgent->new;
    $ua->agent("$0/0.1 " . $ua->agent);
    $ua->agent("Mozilla/8.0");

    my $req = new HTTP::Request 'GET' => "$url";
    $req->header('Accept' => 'text/html');

    # send request
    $response_u = $ua->request($req);

    die "Error: ", $response_u->status_line unless $response_u->is_success;

    my $root = HTML::TreeBuilder->new;
    $root->parse($response_u->content);

    my @gu = $root->find_by_attribute("id", "thumbnails");

    my %urls = ();

    foreach my $g (@gu) {
        my @as = $g->find_by_tag_name('a');

        foreach $a (@as) {
            my $u = $a->attr("href");

            if ($u =~ /^\//) {
                $urls{"http://example.com"."$u"} = 1;
            }
        }
    }

    return %urls;
}

4 个答案:

答案 0 :(得分:10)

最接近的匹配可能是httpclient,其目标是相当于LWP。但是,根据您的计划,可能会有更好的选择。如果您计划关注链接,填写表单等以便抓取网页内容,您可以使用{per}模块中相同名称的Mechanize。还有更多特定于Ruby的宝石,例如优秀的Rest-clientHTTParty(我个人最喜欢的)。有关更大的列表,请参阅HTTP Clients category of Ruby Toolbox

更新:这是一个如何在Mechanize中找到页面上所有链接的示例(Ruby,但它在Perl中类似):

require 'rubygems'
require 'mechanize'

agent = Mechanize.new

page = agent.get('http://example.com/')

page.links.each do |link|
  puts link.text
end

P.S。作为一个前Perler我自己,我曾经担心放弃优秀的CPAN - 我会把自己画成Ruby的角落吗?难道我无法找到我所依赖的模块的等价物吗?事实证明这根本不是问题,事实上最近恰恰相反:Ruby(以及Python)往往是第一个获得客户支持新平台/ Web服务等的人。

答案 1 :(得分:3)

这是你的函数在ruby中的样子。

require 'rubygems'
require "mechanize"

def get_gallery_urls url
    ua = Mechanize.new
    ua.user_agent = "Mozilla/8.0"
    urls = {}

    doc = ua.get url
    doc.search("#thumbnails a").each do |a|
        u = a["href"]
        urls["http://example.com#{u}"] = 1 if u =~ /^\//
    end

    urls
end

好多了:)

答案 2 :(得分:3)

我使用Perl多年,并喜欢LWP。这是一个很棒的工具。但是,这是我如何从页面中提取URL。这不是一个网站,但这很容易:

require 'open-uri'
require 'uri'

urls = URI.extract(open('http://example.com').read)
puts urls

结果输出如下:

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
http://www.w3.org/1999/xhtml
http://www.icann.org/
mailto:iana@iana.org?subject=General%20website%20feedback

将其写为方法:

require 'open-uri'
require 'uri'

def get_gallery_urls(url)
  URI.extract(open(url).read)
end

或者,在执行Ruby-way时更接近原始函数:

def get_gallery_urls(url)
  URI.extract(open(url).read).map{ |u| 
    URI.parse(u).host ? u : URI.join(url, u).to_s
  }
end

或者,更接近原始代码:

require 'nokogiri'
require 'open-uri'
require 'uri'

def get_gallery_urls(url)
  Nokogiri::HTML(
    open(url)
  )
    .at('#thumbnails')
    .search('a')
    .map{ |link|
      href = link['href']
      URI.parse(link[href]).host \
        ? href \
        : URI.join(url, href).to_s
    }
end

吸引我使用Ruby的一个原因是它具有可读性,同时仍然简洁。

如果你想推出自己的基于TCP / IP的功能,Ruby的标准网络库是起点。默认情况下,您会得到:

net/ftp
net/http
net/imap
net/pop
net/smtp
net/telnet

使用基于SSL的ssh,scp,sftp和其他可用作宝石的。使用gem search net -r | grep ^net-查看简短列表。

答案 3 :(得分:1)

与使用LWP(甚至是WWW::Mechanize)相比,对于任何查看此问题且需要了解使用Perl进行常规网络抓取的更简单/更好/不同替代方案的人来说,这更能解决问题

以下是CPAN上的网页抓取模块的快速选择:

NB。以上只是按字母顺序排列,所以请选择你喜欢的毒药:)

对于我最近的网页抓取,我一直在使用pQuery。你可以看到有很多examples of usage on SO

以下是使用get_gallery_urls的{​​{1}}示例:

pQuery

PS。正如Daxim在评论中所说,有很多优秀的Perl工具可用于网页抓取。最难的部分就是选择使用哪一个!