Nokogiri结果没有循环

时间:2017-03-08 23:21:17

标签: ruby-on-rails ruby web-scraping nokogiri

我想了解如何刮页。

结果未在视图页面上循环。它只显示第一个。为什么呢?

LinksController:

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 %>

仅显示第一批结果的屏幕截图:

enter image description here

路线:

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

3 个答案:

答案 0 :(得分:1)

这可能是因为你只是在抓第一页的结果。如果你去网址,你正在刮擦&#34; https://losangeles.craigslist.org/search/web&#34;你可以看到它只显示前100个结果。如果向下滚动并单击&#34; next&#34;该链接更改为&#34; https://losangeles.craigslist.org/search/web?s=100&#34;。如果要刮取所有结果,则需要创建一个方法来刮取结果的每一页。

答案 1 :(得分:0)

在@craigslist_info的迭代中,您没有引用占位符,craig,而是仅引用@link_info和@date。这只会产生一个结果。在您的迭代中,您想要访问“craig”的link_info和日期。

<% @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 %>

答案 2 :(得分:0)

您正在迭代@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