Nokogiri 结果不循环
Nokogiri results not looping
我正在尝试了解如何抓取页面。
结果没有在视图页面上循环。它只显示第一个。为什么?
链接控制器:
class LinksController < ApplicationController
def craigslist_scrape
require 'open-uri'
url = "https://losangeles.craigslist.org/search/web"
page = Nokogiri::HTML(open(url))
@craigslist_info = page.css("ul.rows")
@link_info = @craigslist_info.at_css("li.result-row p.result-info a.result-title.hdrlnk")
@date = @craigslist_info.at_css("li.result-row p.result-info time.result-date")
end
end
查看页面:craigslist_scrape.html.erb:
<% @craigslist_info.each do |craig| %>
<p><%= "Title of the job: #{@link_info.text}" %></p>
<p><%= "Date: #{@date.text}" %></p>
<% end %>
仅第一个结果的屏幕截图:
路线:
Rails.application.routes.draw do
root 'links#craigslist_scrape'
end
架构:
ActiveRecord::Schema.define(version: 20170308223314) do
enable_extension "plpgsql"
create_table "links", force: :cascade do |t|
t.string "link_info"
t.string "date"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
在 @craigslist_info 的迭代中,您没有引用占位符 craig,而是仅引用 @link_info 和 @date。这只会产生一个结果。在您的迭代中,您想要访问 link_info 和 "craig" 的日期。
<% @craigslist_info.each do |craig| %>
<% link_info = craig.at_css("li.result-row p.result-info a.result-title.hdrlnk") %>
<% date = craig.at_css("li.result-row p.result-info time.result-date")%>
<p><%= "Title of the job: #{link_info.text}" %></p>
<p><%= "Date: #{date.text}" %></p>
<% end %>
这可能是因为您只抓取了结果的第一页。如果你去 url 你正在抓取“https://losangeles.craigslist.org/search/web" you can see that it's only showing you the first 100 results. If you scroll down and click "next" the link changes to "https://losangeles.craigslist.org/search/web?s=100”。如果你想抓取所有结果,你需要创建一个方法来抓取结果的每一页。
您正在遍历 @craigslist_info
,但 .css("ul.rows")
只会选取一个元素。每次调用 .at_css
时,您也会覆盖以前的元素
试试这样的:
page = Nokogiri::HTML(open(url))
@links = page.css("li.result-row p.result-info a.result-title.hdrlnk")
@dates = page.css("li.result-row p.result-info time.result-date")
然后在您看来:
<% @links.each_with_index do |link, index| %>
<p><%= "Title of the job: #{link.text}" %></p>
<p><%= "Date: #{@dates[index].text}" %></p>
<% end %>
如果您想整理一下,还可以将抓取的数据建模为更易于理解的形式。例如:
results = page.css("li.result-row p.result-info")
@result_objects = results.map { |o|
OpenStruct.new(
link: o.at_css("a.result-title.hdrlnk"),
date: o.at_css("time.result-date")
)
}
然后遍历 @result_objects
,知道您可以访问每个 .link
和 .date
。
我正在尝试了解如何抓取页面。
结果没有在视图页面上循环。它只显示第一个。为什么?
链接控制器:
class LinksController < ApplicationController
def craigslist_scrape
require 'open-uri'
url = "https://losangeles.craigslist.org/search/web"
page = Nokogiri::HTML(open(url))
@craigslist_info = page.css("ul.rows")
@link_info = @craigslist_info.at_css("li.result-row p.result-info a.result-title.hdrlnk")
@date = @craigslist_info.at_css("li.result-row p.result-info time.result-date")
end
end
查看页面:craigslist_scrape.html.erb:
<% @craigslist_info.each do |craig| %>
<p><%= "Title of the job: #{@link_info.text}" %></p>
<p><%= "Date: #{@date.text}" %></p>
<% end %>
仅第一个结果的屏幕截图:
路线:
Rails.application.routes.draw do
root 'links#craigslist_scrape'
end
架构:
ActiveRecord::Schema.define(version: 20170308223314) do
enable_extension "plpgsql"
create_table "links", force: :cascade do |t|
t.string "link_info"
t.string "date"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
在 @craigslist_info 的迭代中,您没有引用占位符 craig,而是仅引用 @link_info 和 @date。这只会产生一个结果。在您的迭代中,您想要访问 link_info 和 "craig" 的日期。
<% @craigslist_info.each do |craig| %>
<% link_info = craig.at_css("li.result-row p.result-info a.result-title.hdrlnk") %>
<% date = craig.at_css("li.result-row p.result-info time.result-date")%>
<p><%= "Title of the job: #{link_info.text}" %></p>
<p><%= "Date: #{date.text}" %></p>
<% end %>
这可能是因为您只抓取了结果的第一页。如果你去 url 你正在抓取“https://losangeles.craigslist.org/search/web" you can see that it's only showing you the first 100 results. If you scroll down and click "next" the link changes to "https://losangeles.craigslist.org/search/web?s=100”。如果你想抓取所有结果,你需要创建一个方法来抓取结果的每一页。
您正在遍历 @craigslist_info
,但 .css("ul.rows")
只会选取一个元素。每次调用 .at_css
试试这样的:
page = Nokogiri::HTML(open(url))
@links = page.css("li.result-row p.result-info a.result-title.hdrlnk")
@dates = page.css("li.result-row p.result-info time.result-date")
然后在您看来:
<% @links.each_with_index do |link, index| %>
<p><%= "Title of the job: #{link.text}" %></p>
<p><%= "Date: #{@dates[index].text}" %></p>
<% end %>
如果您想整理一下,还可以将抓取的数据建模为更易于理解的形式。例如:
results = page.css("li.result-row p.result-info")
@result_objects = results.map { |o|
OpenStruct.new(
link: o.at_css("a.result-title.hdrlnk"),
date: o.at_css("time.result-date")
)
}
然后遍历 @result_objects
,知道您可以访问每个 .link
和 .date
。