【问题标题】:Scrape website with Ruby based on embedded CSS styles使用基于嵌入式 CSS 样式的 Ruby 抓取网站
【发布时间】:2013-05-22 23:28:17
【问题描述】:

过去,我已经成功地使用Nokogiri 使用简单的 Ruby 脚本抓取网站。对于当前项目,我需要抓取一个仅使用内联 CSS 的网站。可以想象,这是一个旧网站。

我必须根据元素的内联 CSS 来定位页面上的特定元素有哪些可能性?看来这对 Nokogiri 是不可能的,还是我忽略了什么?

更新:可以找到一个示例here。我基本上需要没有脚注的主要内容。后者的字体较小,并在每个部分下方分组。

【问题讨论】:

  • 如果可能的话,分享您要废弃的网站?
  • 我已经用一个例子更新了这个问题。
  • 啊,保存为 HTML 的旧 Word 文档。零结构,所有内联样式。祝你好运。
  • 举一些你想找到的元素的例子。还要说明您是如何尝试访问它们的。
  • @theTinMan 我已根据您的问题更新了问题。

标签: ruby web-scraping nokogiri


【解决方案1】:

我要教你如何钓鱼。与试图找到我想要的相比,有时找到我不想要的并将其删除要容易得多。

从这段代码开始:

require 'nokogiri'
require 'open-uri'

URL = 'http://www.eximsystems.com/LaVerdad/Antiguo/Gn/Genesis.htm'
FOOTNOTE_ACCESSORS = [
  'span[style*="font-size: 8.0pt"]',
  'span[style*="font-size:8.0pt"]',
  'span[style*="font-size: 7.5pt"]',
  'span[style*="font-size:7.5pt"]',
  'font[size="1"]'
].join(',')

doc = Nokogiri.HTML(open(URL))
doc.search(FOOTNOTE_ACCESSORS).each do |footnote|
  footnote.remove
end

File.write(File.basename(URI.parse(URL).path), doc.to_html)

运行它,然后在浏览器中打开生成的 HTML 文件。滚动文件以查找要删除的脚注。选择部分文本,然后使用“检查元素”或任何您拥有的工具,可以在页面源中找到所选文本。在该文本中找到一些独特的东西,以便将其与您要保留的文本隔离开来。例如,我使用<span><font> 标签中的字体大小来定位脚注。

继续向FOOTNOTE_ACCESSORS 数组添加访问器,直到删除所有不需要的元素。

这段代码并不完整,也没有像我通常为这类任务编写的那样紧凑,但它会让您了解如何完成这项特定任务。


这是一个更灵活的版本:

require 'nokogiri'
require 'open-uri'

URL = 'http://www.eximsystems.com/LaVerdad/Antiguo/Gn/Genesis.htm'
FOOTNOTE_ACCESSORS = [
  'span[style*="font-size: 8.0pt"]',
  'span[style*="font-size:8.0pt"]',
  'span[style*="font-size: 7.5pt"]',
  'span[style*="font-size:7.5pt"]',
  'font[size="1"]',
]

doc = Nokogiri.HTML(open(URL))
FOOTNOTE_ACCESSORS.each do |accessor|
  doc.search(accessor).each do |footnote|
    footnote.remove
  end
end

File.write(File.basename(URI.parse(URL).path), doc.to_html)

主要区别在于之前的版本假定FOOTNOTE_ACCESSORS 中的所有条目都是CSS。有了这个改变,也可以使用 XPath。随着条目的迭代,代码将需要更长的时间来运行,但是使用 XPath 进行挖掘的能力对您来说可能是值得的。

【讨论】:

  • 这是一个可以创造奇迹的聪明策略。是时候钓鱼了。
  • 这是在野外与 HTML 进行多次战斗的结果,从我在 Perl 中编写蜘蛛和爬虫时开始,人们就认为 Word 生成的 HTML 是令人沮丧的。有时我们需要移动岩石才能看到黄金。
  • @BartJacobs,我添加了一些小调整。
【解决方案2】:

你可以这样做:

doc.css('*[style*="foo"]')

这将选择任何在其样式属性中出现foo 的元素。

【讨论】:

  • 不明白[style*="foo"]'[style ="foo"]'的区别
  • 你为什么不阅读我指给你的文档然后告诉我?
  • @pguardiario 这出奇的好。但是,我对 Tin Man 的方法有更好的命中/未命中率,这就是我接受他的回答的原因。感谢您的帮助。
猜你喜欢
  • 2015-05-09
  • 2020-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 2014-08-02
  • 2017-01-29
相关资源
最近更新 更多