Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 使用Nokogiri和Mechanize进行刮网_Ruby_Nokogiri_Mechanize - Fatal编程技术网

Ruby 使用Nokogiri和Mechanize进行刮网

Ruby 使用Nokogiri和Mechanize进行刮网,ruby,nokogiri,mechanize,Ruby,Nokogiri,Mechanize,我正在解析prada.com,希望从div类“nextItem”中获取数据,并获取其名称和价格。这是我的密码: require 'rubygems' require 'mechanize' require 'nokogiri' require 'open-uri' agent = Mechanize.new page = agent.get('http://www.prada.com/en/US/e-store/department/woman/handbags.html?cmp=from_ho

我正在解析prada.com,希望从div类“nextItem”中获取数据,并获取其名称和价格。这是我的密码:

require 'rubygems'
require 'mechanize'
require 'nokogiri'
require 'open-uri'
agent = Mechanize.new
page = agent.get('http://www.prada.com/en/US/e-store/department/woman/handbags.html?cmp=from_home')
fp = File.new('prada_prices','w')
html_doc = Nokogiri::HTML(page)
page = html_doc.xpath("//ol[@class='nextItem']")
page.each do {|i| fp.write(i.text + "\n")}
end
我得到一个错误,没有输出。我想我正在做的是实例化一个mechanize对象并将其称为代理。 然后创建一个页面变量并将提供的url分配给它。 然后使用传入的mechanize url创建一个nokogiri对象变量 然后在url中搜索所有名为nextItem的类引用 然后打印其中包含的所有数据


有人能告诉我哪里出了问题吗?

以下是错误的部分:

  • 再次检查块语法-使用
    {}
    do
    /
    end
    ,但不能同时使用两者
  • Mechanize#get
    返回一个充当Nokogiri文档的
    Mechanize::Page
    ,至少它有
    search
    xpath
    css
    。使用它们,而不是试图将文档强制为Nokogiri::HTML对象
  • 当您不直接使用它们时,不需要
    要求“openuri”
    ,也不需要
    要求“nokogiri”
  • 在继续抓取网页之前,最后检查一下Ruby的基础知识
以下是修复代码:

require 'rubygems'
require 'mechanize'
agent = Mechanize.new
page = agent.get('http://www.prada.com/en/US/e-store/department/woman/handbags.html?cmp=from_home')
fp = File.new('prada_prices','w')
page = page.search("//ol[@class='nextItem']").each do |i| 
  fp.write(i.text + "\n")
end
fp.close

由于Prada的网站通过JavaScript动态加载其内容,因此很难获取其内容。有关详细信息,请参阅“”

一般来说,在获得页面后,使用Mechanize:

page = agent.get(page_url)
您可以使用CSS选择器轻松搜索项目,并搜索数据:

next_items = page.search(".fooClass")

next_items.each do |item|
  price = item.search(".fooPrice").text
end

然后只需根据需要处理字符串或生成哈希。

Prada似乎以某种方式隐藏了名称。。。你知道这个名字在HTML中存储在哪里吗?他们似乎通过JS加载了很多东西。。。所以刮起来可能很难。刚刚测试了我的尝试,但不起作用…我尝试了你的方法,但仍然没有得到任何价格输出。我认为我如何理解DOM存在问题?HTML的签名存储在一个名为nextItem的深度嵌套的div类中,每个项目都包含一个标识项目的id,以及关于价格的文本require'rubygems'require'mechanize'agent=mechanize.new page=agent.get(')item=page.search(“.nextItem”)item.each do | item | price=item.search(.itemPrice).text放入price end如果查看站点的源代码,您将看到未加载
nextItem
div。它们是通过JS动态加载的。检查,如回答中所述。使用
文件的块形式。打开
而不是
文件。新建
并分配给变量。另外,混合
do
/
end
{
/
}
也可以。对于多行
每个
类型的块,使用
do
/
end
。使用
{
/
}
处理单行和块,如返回值的
map
。感谢编辑@theTinMan,但我编辑了他的代码。给了他一些一般性的建议。尽可能少地修改代码以使其更易于理解。我知道ruby风格指南,但我认为其中的任何内容都不会对answear有所帮助。不必为了保持熟悉而重用他们的代码。传播糟糕的编程实践是一种伤害。而是在应该如何编写代码的上下文中显示修复。这不仅仅是为了让他们的代码工作,而是为了展示他们应该如何让代码工作。这是给某人一条鱼和教他们如何钓鱼之间的区别。你对糟糕的编程实践是正确的,但在这些代码中,只是一些表面上的改变,实际上并没有太大的改变。如果使用
File#open
会更好,但差别不大。我认为没有必要解释我对
do/end
的决定,而是
{}
,它只会给answear.Jeez带来噪音。这几乎就像@hahcho试图在他所在的地方而不是他“应该”所在的地方与OP会面。就像…某种…什么词?…老师!