遍历所有 <dd> 标签并通过 Mechanize/Nokogiri 提取特定信息

Loop over all the <dd> tags and extract specefic information via Mechanize/Nokogiri

我知道访问网站的基本知识等等(我昨天才开始学习),但是我现在想提取。我查看了 Mechanize/Nokogiri 的许多教程,但每个教程都有不同的做事方式,这让我感到困惑。我想要一个直接大胆的方法来做到这一点:

我有这个网站:http://openie.allenai.org/sentences/rel=contains&arg2=antioxidant&title=Green+tea

并且我想以结构化的方式提取某些内容。如果我检查此网页的元素并转到正文,我会在 <dl class="dl-horizontal"> 下看到很多 <dd>..</dd>。他们每个人都有一个 <a> 部分,其中包含一个 href。我想提取此 href 和文本 ex <b>green tea</b> 的粗体部分。

我创建了一个简单的结构:

info = Struct.new(:ObjectID, :SourceID) 因此从每个 <dd> 中将粗体文本添加到对象 ID 并将 href 添加到源 ID。

这是我的代码的开头,只是检索没有提取:

agent = Mechanize.new { |agent| agent.user_agent_alias = "Windows Chrome" }
html = agent.get('http://openie.allenai.org/sentences/?rel=contains&arg2=antioxidant&title=Green+tea').body
html_doc = Nokogiri::HTML(html)

另一件事是我很困惑是直接使用Nokogiri还是通过Mechanize。问题是 Mechanize 提供的文档不够,所以我考虑单独使用它。

现在我想知道如何遍历这些并提取信息。

下面是一个示例,说明如何从您描述的锚元素中解析粗体文本和 href 属性:

require 'nokogiri'
require 'open-uri'

url = 'http://openie.allenai.org/sentences/?rel=contains&arg2=antioxidant&title=Green%20tea'
doc = Nokogiri::HTML(open(url))

doc.xpath('//dd/*/a').each do |a|
  text = a.xpath('.//b').map {|b| b.text.gsub(/\s+/, ' ').strip}
  href = a['href']
  puts "OK: text=#{text.inspect}, href=#{href.inspect}"
end

# OK: text=["Green tea", "many antioxidants"], href="http://www.talbottteas.com/category_s/55.htm"
# OK: text=["Green tea", "potent antioxidants"], href="http://www.skin-care-experts.com/tag/best-skin-care/page/4"
# OK: text=["Green tea", "potent antioxidants"], href="http://www.specialitybrand.com/news/view/207.html"

简而言之,此解决方案在两个地方使用了 XPath:

  1. 最初找到每个 dd 元素下面的每个 a 元素。
  2. 然后在上面#1 中的 a 中找到每个 b 元素。

最后一个技巧是将 "b" 元素中的文本清理成可以呈现的内容,当然,您可能希望它看起来有所不同。