【问题标题】:Scraping separate sets of items from a website with Ruby & Nokogiri使用 Ruby 和 Nokogiri 从网站上抓取单独的项目集
【发布时间】:2021-11-21 19:22:28
【问题描述】:

我正在为学校开展一个项目,但在网站的 HTML 中查找正确的 CSS 选择器以提取我正在寻找的数据时遇到了问题。这也是我第一次使用网络抓取,而且我对 Ruby 也很陌生,所以如果这是一个愚蠢的问题,我深表歉意。

我已经成功解析了第一组数据(虽然我确信有更好的方法可以做到这一点,但我的方法是有效的,但欢迎对此提供反馈):

网站是 Platinumgod.co.uk 供参考。

我为第一部分抓取的 HTML 如下(以及作为示例列出的第一项):

<div class="repentanceitems-container">
  <h2>
    "Repentance Items "
    <span class="rep-item-ttl">(169)</span>
  </h2>
  <li class="textbox" data-tid="42.5" data-cid="42" data-sid="263">
    <a
      <div onclick class="item reb-itm-new re-itm263"></div>
      <span>
        <p class="item-title">Clear Rune</p>
        <p class="r-itemid">ItemID: 263</p>
        <p class="pickup">"Rune mimic"</p>
        <p class="quality">Quality: 2</p>
        <p>"When used, copies the effect of the Rune or Soul stone you are holding (like the Blank Card)"</p>
        <p>Drops a random rune on the floor when picked up</p>
        <p>The recharge time of this item depends on the Rune/Soul Stone held:</p>
        <p>1 room: Soul of Lazarus</p>
        <p>2 rooms: Rune of Ansuz, Rune of Berkano, Rune of Hagalaz, Soul of Cain</p>
        <p>3 rooms: Rune of Algiz, Blank Rune, Soul of Magdalene, Soul of Judas, Soul of ???, Soul of the Lost</p>
        <p>4 rooms: Rune of Ehwaz, Rune of Perthro, Black Rune, Soul of Isaac, Soul of Eve, Soul of Eden, Soul of the Forgotten, Soul of Jacob and Esau</p>
        <p>6 rooms: Rune of Dagaz, Soul of Samson, Soul of Azazel, Soul of Apollyon, Soul of Bethany</p>
        <p>12 rooms: Rune of Jera, Soul of Lilith, Soul of the Keeper</p>
        <ul>
          <p>Type: Active</p>
          <p>Recharge time: Varies</p>
          <p>Item Pool: Secret Room, Crane Game</p>
        </ul>
        <p class="tags">* Secret Room</p>
      </span>
    </a>
  </li>

这只是 Repentance Items 类别中的一个项目的示例,所以这是我解析该类别中每个项目的所有信息的代码:

# Repentance Items
repentance_items = []
html.at(".repentanceitems-container").css("li.textbox").each do |item |
    item_name = item.css("a span p.item-title").text
    item_id = item.css("a span p.r-itemid").text.sub(/^ItemID: /, "")
    pickup_text = item.css("a span p.pickup").text.gsub("\"", "")
    quality = item.css("a span p.quality").text.sub(/^Quality: /, "")
    use = item.css(".quality ~ p:not(.tags)").map { |row| row.text }

    item_type = item.css("a span ul")
    item.css("a span ul").each.map do |child|
        item_type = child.css("p")[0].text.sub(/^Type: /, "")
        if child.css("p")[1].text.match "Recharge time"
            recharge_time = child.css("p")[1].text.sub(/^Recharge time: /, "")
            item_pool = child.css("p")[2].text.sub(/^Item Pool: /, "").gsub(/,\s*$/m, "").split(", ")
        else
            recharge_time = "N/A"
            item_pool = child.css("p")[1].text.sub(/^Item Pool: /, "").gsub(/,\s*$/m, "").split(", ")
        end
        repentance_items << {name: item_name, item_id: item_id, pickup_text: pickup_text, quality: quality, use: use, item_type: item_type, recharge_time: recharge_time, item_pool: item_pool}
    end
end

我面临的问题是,当我尝试抓取下一个类别,即忏悔物品饰品时,我不确定 CSS 选择器应该是什么才能获取此信息,因为很多相同的类都是与 Repentance Items HTML & 中使用的一样,所以我只得到与以前相同的项目。小饰品的 HTML 如下(连同作为示例列出的第一项):

<div class="repentanceitems-container">
  <h2>
    "Repentance Trinkets "
    <span class="a-item-ttl">(61)</span>
  </h2>
  <li class="textbox" data-tid="1000" data-cid="804" data-sid="10129">
    <a
      <div onclick class="item rep-item rep-trink rep-junxx129"></div>
      <span>
        <p class="item-title">Jawbreaker</p>
        <p class="r-itemid">TrinketID: 129</p>
        <p class="pickup">"Don't chew on it"</p>
        <p>Tears have a chance to become a tooth, dealing x3.2 damage, similar to Tough Love</p>
        <p>The chance to fire a tooth with this trinket is affected by your Luck stat</p>
        <p>At +0 luck you have ~12% chance for this effect to activate</p>
        <p>At +9 luck every tear you fire will be a tooth</p>
        <p class="tags">*, </p>
      </span>
    </a>
  </li>

我不知道从哪里开始只选择这些项目。如果我使用我的代码第一部分中使用的相同选择器,它显然只是重新拉入悔改物品而不是小饰品。

希望我已经解释得足够好,但请随时问我更多问题,我会尽力解释得更好。

非常感谢大家提前帮助我!

【问题讨论】:

  • 这是一个艰难的起点,因为它没有结构,实际上甚至不是有效的 HTML。 &lt;span&gt; tags 只允许包含短语内容 - 而不是 &lt;p&gt; 是流内容。有没有更好/更简单的页面可供您开始?
  • 不幸的是,我使用的页面是列出所有项目的网站主页。每个类别没有单独的页面,也没有任何项目链接到单独的页面,只有一个弹出窗口,其中包含我抓取的每个类别的信息。我对网页无能为力,因为它不是我的。

标签: ruby web-scraping nokogiri


【解决方案1】:

也许您可以先将第一条选择器线分成两部分:一个用于捕获容器,另一个用于查找项目。 这可能看起来像这样(未经测试):

repentance_items = []
repentance_trinklets = []
html.at(".repentanceitems-container").each do |container|
  
  # Check to know in what category you are, so in which table to add the results, something like:
  repentance_target = if container.css('h2').text =~ /items/i
    repentance_items
  else
    repentance_trinklets
  end

  css("li.textbox").each do |item|
    # your current logic

    # affectation in the correct results array
    repentance_target << ...
  end

end

最后这两个数组应该填充正确的项目

这有点草,但我希望能有所帮助,如果有不清楚的地方请告诉我

【讨论】:

    猜你喜欢
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    • 2022-07-28
    • 2014-09-11
    相关资源
    最近更新 更多