Nokogiri、REXML、Rubyを1か月間使っています。クロールしようとしているこの巨大なデータベースがあります。私がスクレイピングしているのは、HTMLリンクとXMLファイルです。
クロールしてCSVファイルに保存したいXMLファイルは正確に43612あります。
私のスクリプトは、おそらく500 xmlファイルをクロールする場合に機能しますが、それよりも大きいと時間がかかりすぎてフリーズするなどの問題が発生します。
ここではコードを分割して読みやすくしました。スクリプト/コード全体はここにあります:https ://gist.github.com/1981074
nokogiriでこれをすべて行う方法が見つからなかったため、2つのライブラリを使用しています。個人的にはREXMLの方が使いやすいと思います。
私の質問:これをすべてクロールするのに1週間もかからないように、どうすれば修正できますか?どうすれば高速に実行できますか?
これが私のスクリプトです:
必要なlibが必要です:
require 'rubygems'
require 'nokogiri'
require 'open-uri'
require 'rexml/document'
require 'csv'
include REXML
そのグラブデータを格納するための配列の束を作成します。
@urls = Array.new
@ID = Array.new
@titleSv = Array.new
@titleEn = Array.new
@identifier = Array.new
@typeOfLevel = Array.new
スペックサイトからすべてのxmlリンクを取得し、@urlsという配列に格納します
htmldoc = Nokogiri::HTML(open('http://testnavet.skolverket.se/SusaNavExport/EmilExporter?GetEvent&EMILVersion=1.1&NotExpired&EEFormOfStudy=normal&EIAcademicType=UoH&SelectEI'))
htmldoc.xpath('//a/@href').each do |links|
@urls << links.content
end
@urls配列をループスローし、xpathで取得するすべての要素ノードを取得します。
@urls.each do |url|
# Loop throw the XML files and grab element nodes
xmldoc = REXML::Document.new(open(url).read)
# Root element
root = xmldoc.root
# Hämtar info-id
@ID << root.attributes["id"]
# TitleSv
xmldoc.elements.each("/educationInfo/titles/title[1] | /ns:educationInfo/ns:titles/ns:title[1]"){
|e| m = e.text
m = m.to_s
next if m.empty?
@titleSv << m
}
次に、それらをCSVファイルに保存します。
CSV.open("eduction_normal.csv", "wb") do |row|
(0..@ID.length - 1).each do |index|
row << [@ID[index], @titleSv[index], @titleEn[index], @identifier[index], @typeOfLevel[index], @typeOfResponsibleBody[index], @courseTyp[index], @credits[index], @degree[index], @preAcademic[index], @subjectCodeVhs[index], @descriptionSv[index], @lastedited[index], @expires[index]]
end
end