我完全被Nokogiri和Rails中的web抓取弄糊涂了。我需要有人向我解释如何从网站获得文章标题,以便在我的Rails应用程序的视图中列出。我可以设法检索irb中的数据,但我不知道如何获得相同的数据显示在我所做的视图中。
我看过一些教程和阅读文档,他们做的一件事让我最困惑的是当他们需要nokogiri或open-uri在他们的例子ruby文件,ruby文件应该放在什么目录?该文件是否与任何控制器相关联以便在我创建的特定视图中显示?
我希望我解释我的问题尽可能清楚没有任何混乱,因为我不想再试图混淆自己,我在我的解释。
看,我要做的是创建一个用户可以注册和登录的应用程序,在他们登录后,他们被重定向到一个有3个链接的页面。这些链接是奥迪,宝马和梅赛德斯-奔驰,根据用户点击哪个链接,用户将被引导到另一个页面,在那里他们会返回一个提到他们想要选择的文章列表。
我希望这个解释是有帮助的,我真的希望有人能提供帮助或给我一些对我有益的文档。
谢谢!
这是我在irb:
中所做的2.1.1 :001 > require 'rubygems'
=> false
2.1.1 :002 > require 'nokogiri'
=> true
2.1.1 :003 > require 'open-uri'
=> true
2.1.1 :004 > page = Nokogiri::HTML(open("http://www.dtm.com/de/News/Archiv/index.html"))
然后我得到了这个返回:
=> #<Nokogiri::HTML::Document:0x814e3b40 name="document" children=[#<Nokogiri::XML::DTD:0x814e37f8 name="HTML">, #<Nokogiri::XML::Element:0x814e358c name="html" children=[#<Nokogiri::XML::Text:0x814e3384 "rn">, #<Nokogiri::XML::Element:0x814e32d0 name="head" children=[#<Nokogiri::XML::Text:0x814e30f0 "rn">, #<Nokogiri::XML::Element:0x814e3028 name="title" children=[#<Nokogiri::XML::Text:0x814e2e48 "DTM | Newsarchiv">]>, #<Nokogiri::XML::Text:0x814e2c90 "rn">, #<Nokogiri::XML::Element:0x814e2bc8 name="meta" attributes=[#<Nokogiri::XML::Attr:0x814e2b64 name="charset" value="utf-8">]>, #<Nokogiri::XML::Text:0x814e2718 "rn">, #<Nokogiri::XML::Element:0x814e2664 name="meta" ...
(我得到了更多,但只是把返回的几行)我假设这是来自页面的原始数据。
然后加上:
2.1.1 :008 > puts page
返回原始HTML内容。
最后我进入:
2.1.1 :014 > page.css("a")
返回页面上的所有链接
我希望用一个真实世界的例子来帮助你。例如,让我们从路透社获取一些数据。
在控制台中试试:
# require your tools make sure you have gem install nokogiri
pry(main)> require 'nokogiri'
pry(main)> require 'open-uri'
# set the url
pry(main)> url = "http://www.reuters.com/finance/stocks/overview?symbol=0005.HK"
# load and assign to a variable
pry(main)> doc = Nokogiri::HTML(open(url))
# take a piece of the site that has an element style .sectionQuote you can use ids also
pry(main)> quote = doc.css(".sectionQuote")
现在,如果你看一下引号,你会看到你将有Nokogiri元素。让我们看看里面:
pry(main)> quote.size
=> 6
pry(main)> quote.first
=> #(Element:0x43ff468 {
name = "div",
attributes = [ #(Attr:0x43ff404 { name = "class", value = "sectionQuote nasdaqChange" })],
children = [
#(Text "nttt"),
#(Element:0x43fef18 {
name = "div",
attributes = [ #(Attr:0x43feeb4 { name = "class", value = "sectionQuoteDetail" })],
children = [
#(Text "ntttt"),
#(Element:0x43fe9c8 { name = "span", attributes = [ #(Attr:0x43fe964 { name = "class", value = "nasdaqChangeHeader" })], children = [ #(Text "0005.HK on Hong Kong Stock")] }),
.....
}),
#(Text "ntt")]
})
您可以看到nokogiri实质上封装了每个DOM元素,因此您可以快速搜索和访问它。
如果你只想简单地显示这个div元素,你可以:
pry(main)> quote.first.to_html
=> "<div class="sectionQuote nasdaqChange">nttt<div class="sectionQuoteDetail">ntttt<span class="nasdaqChangeHeader">0005.HK on Hong Kong Stock</span>ntttt<br class="clear"><br class="clear">ntttt<span style="font-size: 23px;">ntttt82.85</span><span>HKD</span><br>ntttt<span class="nasdaqChangeTime">14 Aug 2014</span>nttt</div>ntt</div>"
,并且可以直接在rails应用程序的视图中使用它。
如果你想更具体地使用单个组件,并通过循环quote变量遍历下一层的元素,在这个例子中,你可以:
pry(main)> quote.each{|p| puts p.inspect}
或者非常具体地获取元素的值,即我们示例中的股票名称:
pry(main)> quote.at_css(".nasdaqChangeHeader").content
=> "0005.HK on Hong Kong Stock"
这是一个非常有用的链接:http://nokogiri.org/tutorials/searching_a_xml_html_document.html
真的希望这有帮助
PS:查看对象内部的提示(http://ruby-doc.org/core-2.1.1/Object.html method-i-inspect)
puts quote.inspect
首先,你可以把nokogiri和openuri放在rails应用程序的gemfile中,这样你就不需要这些库了。
你的流刮站点应该是:
# put this code on your controller
web_site = params[:web_site] # could be http://www.bmw.com/com/en/
@doc = Nokogiri::HTML(open(web_site))
#then you can iterate over the document in your view
<% @doc.css('.standardTeaser').each do |teaser_bmw| %>
<p>teaser_bmw.css('.headline').text </p>
#other content of teaser you can search here
<% end %>
因此,要抓取网站,您需要从网站获取html并找到您想要抓取的内容。如果你知道一些css选择器的基础知识,这将是很容易做到的。我的例子不考虑如果你想保存数据在数据库中…但是,如果您愿意,您只需要创建一个表,其中包含需要保存的字段,然后在解析html后创建一条记录。
你明白了吗?