一个月以来,我一直在研究 Nokogiri、REXML 和 Ruby。我有这个巨大的数据库,我正在尝试爬取。我正在抓取的内容是 HTML 链接和 XML 文件。
我想要抓取并存储在 CSV 文件中的正是 43612 个 XML 文件。
如果抓取 500 个 xml 文件,我的脚本可以工作,但更大的文件需要太多时间并且它会冻结或其他东西。
我在这里将代码分成几部分,以便于阅读,整个脚本/代码在这里:https ://gist.github.com/1981074
我正在使用两个库,因为我找不到在 nokogiri 中完成这一切的方法。我个人觉得 REXML 更容易使用。
我的问题:如何解决它,这样我就不会在一周内爬完这一切?如何让它运行得更快?
这是我的脚本:
需要必要的库:
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