2011-10-06 53 views
1

我有一些数据文件从具有以下格式的数据仓库处理:如何在Ruby中抓取,分析和抓取文件?

:header 1 ... 
:header n 
# remarks 1 ... 
# remarks n 
# column header 1 
# column header 2 
DATA ROWS 
(Example: "#### ## ## ##### ######## ####### ###afp##  ##e###") 

的数据通过空格分开并有数字和其他字符的ASCII。这些数据中的一部分将被拆分并变得更有意义。

所有的数据将进入一个数据库,最初一个SQLite数据库进行开发,然后推到另一个,更持久,存储。

这些文件将在实际上是通过HTTP从远程服务器拉,我将不得不爬一点得到一些吧,因为他们跨越文件夹和许多文件。

我希望得到一些输入的最佳工具和方法可以完成这一任务的“红宝石路”,以及抽象出一些这方面的东西。否则,我会解决它,可能类似于我以前在Perl或其他此类方法中的处理方式。

我一直在想着用OpenURI来打开每个url,然后如果输入的是HTML收集链接来抓取,否则处理数据。我会使用String.scan将文件每次适当地拆分成一个多维数组,根据数据提供者建立的格式解析每个组件。完成后,将数据推入数据库。移至下一个输入文件/ uri。冲洗并重复。

我想我必须失去一些库,那些更有经验将使用清洁/加快这一进程的显着,使剧本更对其他数据集重用灵活。

此外,我将图形和可视化这一数据以及生成报表,因此,或许应该太考虑。

任何输入可能是更好的方法或库只是这样吗?

+0

你可以用“#### ## ##”之类的东西来拆分行。split(/ \ s + /)你可能想要活动记录来做db插入 – pguardiario

+0

好点,我认为你是现货关于ActiveRecord。 – ylluminate

+0

另请参阅:http://stackoverflow.com/questions/4981379/what-are-some-good-ruby-based-web-crawlers –

回答

2

你的问题主要关注“低层次”细节 - 解析URL等等。 “Ruby Way”的一个关键方面是“不要重新发明轮子”。利用现有的库。 :)

我的建议?首先,利用诸如spideranemone的履带。其次,使用Nokogiri进行HTML/XML解析。第三,存储结果。我建议你这样做,因为你以后可能会做不同的分析,而且你不想扔掉蜘蛛的辛苦工作。

不知道你的约束太多,我会看看你的结果存储在MongoDB。想到这个之后,我做了一个快速搜索,并找到一个很好的教程Scraping a blog with Anemone and MongoDB

1

嗨,我会开始仔细研究一下名为Mechanize的宝石,然后再引发任何基本的开放式uri的东西 - 因为它被构建为机械化。这是一款出色的,快速且易于使用的gem,用于自动抓取网页。由于你的数据格式非常奇怪(至少与json,xml或html相比),我不认为你会使用内置解析器 - 但你仍然可以看看它。它被称为nokogiri,并且非常聪明。但最后,在抓取和获取资源之后,您可能不得不使用一些优秀的正则表达式。

祝你好运!

+0

对。我在很多情况下使用nokogiri,但是这个特定的一个只是在字符串处理中用正则表达式解析文档。我很可能会很快转向机械化。我注意到了这一点,但只是简单地从另一条路径开始,对于目前为止处理的约1000万条条目,它效果很好。 – ylluminate

+0

太棒了! :-)机械化实际上只是一个非常简单的库,用于填写表单,点击链接和做请求 - nokgiri正在幕后推动它,所以这对你来说不是那么具有挑战性。 –

+0

机械化当然可以帮助,但它并不旨在帮助您实现网络抓取的实际过程 –

2

我大概写了bajillion蜘蛛和现场分析,发现Ruby有一些很好的工具,应该使这是一个简单的过程。

OpenURI可以很容易地检索页面。

URI.extract可以很容易找到页面中的链接。从文档:

说明

提取物从一个字符串的URI。如果给出的块,遍历所有匹配的URI。如果给定块或匹配数组,则返回nil。

require "uri" 

    URI.extract("text here http://foo.example.org/bla and here mailto:[email protected] and here also.") 
    # => ["http://foo.example.com/bla", "mailto:[email protected]"] 

简单的,未经检验的,逻辑开始可能看起来像:

require "openuri" 
require "uri" 

urls_to_scan = %w[ 
    http://www.example.com/page1 
    http://www.example.com/page2 
] 

loop do 
    break if urls_to_scan.empty? 
    url = urls_to_scan.shift 
    html = open(url).read 

    # you probably want to do something to make sure the URLs are not 
    # pointing outside the site you're walking. 
    # 
    # Something like: 
    # 
    #  URI.extract(html).select{ |u| u[%r{^http://www\.example\.com}i] } 
    # 
    new_urls = URI.extract(html) 

    if (new_urls.any?) 
    urls_to_scan += new_urls 
    else 
    ; # parse your file as data using the content in html 
    end 
end 

除非你拥有您所抓取的网站,你想成为善良温柔:不要为运行尽可能快,因为它不是你的管道。请注意该网站的robot.txt文件或被禁止的风险。

Ruby有真正的网络爬虫宝石,但基本的任务是如此简单,我从来不打扰他们。如果你想查看其他的选择,请访问一些关于这个主题的SO的其他问题的链接。

如果您需要更强大的功能或灵活性,Nokogiri gem简化了解析HTML的工作,允许您使用CSS访问器搜索感兴趣的标签。有一些非常强大的宝石,可以很容易地抓取页面,如typhoeus

最后,尽管在某些注释中推荐的ActiveRecord很好,但在Rails之外使用它的文档可能很困难或令人困惑。我建议使用Sequel。这是一个很棒的ORM,非常灵活,并且有据可查。

+0

由于这是一个Rails应用程序,它最终更容易将其转换为AR和Sequel。它必须每隔x分钟从heroku上的数据库中随时取消,因此在拉动之前同时推送就好了,所以它正在运行。非常感谢。 – ylluminate