【发布时间】:2014-03-30 00:01:09
【问题描述】:
我刚刚编写了我的第一个 ruby 程序,它是一个简单的解析器。我打算用 ruby 和 nokogiri 解析一组 200 个左右的本地 .htm 文件,并将所有内容输出到一个 .csv 文件中。
本地文件的组织方式如下:
root\region_name1\city_name1.htm
root\region_name1\city_name2.htm
root\region_name1\city_name3.htm
root\region_name2\city_name1.htm
...
上述 .htm 文件中的相关 html 源代码如下所示:
<div class="media-body">
<h4 class="list-group-item-heading"><a ng-href="#/clubs/2001103" class="ng-binding" href="http://www.vereinssuche-nrw.de/#/clubs/2001103">DJK Arminia Eilendorf 1919 e. V.</a> <small ng-show="item.distance > 0" class="ng-binding" style="display: none;">0 km</small></h4>
<div class="row">
<div class="col-12 col-lg-6 ng-binding">
<span ng-show="item.geoadresse.strasse" class="ng-binding">Ulmenstraße 12<br></span>52080 Aachen<br>
<a ng-href="tel:0241 551424" ng-show="item.telefon" class="ng-binding" href="unsafe:tel:0241 551424">Tel.: 0241 551424<br></a>
<a ng-href="http://www.DJK-Arminia-Eilendorf.de" ng-show="item.webseite" target="_blank" class="ng-binding" href="http://www.djk-arminia-eilendorf.de/">http://www.DJK-Arminia-Eilendorf.de</a>
</div>
<div class="col-lg-6 col-12 visible-lg event-list">
<b>Veranstaltungen</b>
<!-- ngRepeat: event in item.veranstaltungen | limitTo:3 -->
<div ng-show="item.veranstaltungen.length == 0" class="text-muted">Keine Veranstaltungen angekündigt.</div>
<div>
</div>
</div>
我的 ruby 代码适用于单个 .htm 文件,并通过 XPath 解析/提取我需要的数据。我不想为所有 200 个 .htm 文件解析每个文件并手动合并 output.csv 文件,而是想自动化整个过程,但我真的不知道该怎么做。
这是我的 ruby 代码:
require 'rubygems'
require 'nokogiri'
require 'csv'
# define arrays including a dummy array which is needed for reasons i do not yet know :P
# remember that you can easily adapt this parser to suit your needs by defining additional variables
# and by adding additional xpath steps (doc.xpath...) below
name = Array.new
strasse = Array.new
plzort = Array.new
tel = Array.new
website = Array.new
dummy = Array.new
doc = Nokogiri::HTML(open("aachen.htm"))
puts doc.class # => Nokogiri::HTML::Document
# search elements via xpath and collect contents in arrays
name = doc.xpath("//div/h4/a").collect {|node| node.text.strip}
strasse = doc.xpath("//div/span[contains(@ng-show,'item.geoadresse.strasse')]").collect {|node| node.text.strip}
plzort = doc.xpath("//div[@id='searchResults']/div/div/div/div/div[1]/text()").collect {|node| node.text.strip}
tel = doc.xpath("//div/a[contains(@ng-show,'item.telefon')]").collect {|node| node.text.strip}
website = doc.xpath("//div/a[contains(@ng-show,'item.webseite')]").collect {|node| node.text.strip}
dummy = doc.xpath("//*[@id='searchResults']/div[39]/div/div/div/div[1]/br").collect {|node| node.text.strip}
plzort.delete("")
# generate CSV file output.csv and force UTF-8
CSV.open("output.csv", "wb:UTF-8") do |csv|
# prepopulate CSV file with column headings
csv << ["name", "strasse", "plzort", "tel", "website", "dummy"]
# repeat extraction process until name array returns nothing i.e. no more elements on page
until name.empty?
# write everything to CSV file
csv << [name.shift, strasse.shift, plzort.shift, tel.shift, website.shift, dummy.shift]
end
end
我已经阅读了 ruby 和 nokogiri 文档,但是我不知道如何继续。
【问题讨论】:
标签: ruby parsing csv xpath nokogiri