using ruby nokogiri to parse randomized class names

There’s probably a better way but…

require 'nokogiri'
require 'open-uri'
doc = Nokogiri::HTML(open("https://www.politico.com/2020-election/results/georgia/"))
votes = doc.css('tr[class*="candidate-row"]').map { |row| row.css('td').map { |cell| cell.content } }
biden_row = votes.find_index { |row| row[0] =~ /biden/i }
trump_row = votes.find_index { |row| row[0] =~ /trump/i }
biden_votes = votes[biden_row][1].split('%')[1]
trump_votes = votes[trump_row][1].split('%')[1]

Edit: from the HTML source the relevant table looks like:

<table class="jsx-1526769828 candidate-table">
  <thead class="jsx-3554868417 table-head">
    <tr class="jsx-3554868417">
      <th class="table-header jsx-3554868417 candidate-name">
        <h5 class="jsx-3554868417">Candidate</h5>
      </th>
      <th class="table-header jsx-3554868417 percent">
        <h5 class="jsx-3554868417">Pct.</h5>
      </th>
      <th class="table-header jsx-3554868417 vote-bar"></th>
    </tr>
  </thead>
  <tbody class="jsx-2085888330 table-head">
    <tr class="jsx-2677388595 candidate-row">
      <td class="jsx-3948343365 candidate-name name-row">
        <div class="jsx-1912693590 name-only candidate-short-name">Biden</div>
        <div class="jsx-3948343365 candidate-party-tag">
          <div class="jsx-1420258095 party-label dem">dem</div>
        </div>
        <div class="jsx-3948343365 candidate-winner-check"></div>
      </td>
      <td class="jsx-3830922081 percent percent-row">
        <div class="candidate-percent-only jsx-3830922081">49.4%</div>
        <div class="candidate-votes-next-to-percent jsx-3830922081">2,450,193</div>
      </td>
      <td class="jsx-3458171655 vote-bar vote-bar-row">
        <div style="width:49.4%" class="jsx-3458171655 bar dem"></div>
      </td>
    </tr>
    <tr class="jsx-2677388595 candidate-row">
      <td class="jsx-3948343365 candidate-name name-row">
        <div class="jsx-1912693590 name-only candidate-short-name">Trump*</div>
        <div class="jsx-3948343365 candidate-party-tag">
          <div class="jsx-1420258095 party-label gop">gop</div>
        </div>
        <div class="jsx-3948343365 candidate-winner-check"></div>
      </td>
      <td class="jsx-3830922081 percent percent-row">
        <div class="candidate-percent-only jsx-3830922081">49.4%</div>
        <div class="candidate-votes-next-to-percent jsx-3830922081">2,448,635</div>
      </td>
      <td class="jsx-3458171655 vote-bar vote-bar-row">
        <div style="width:49.4%" class="jsx-3458171655 bar gop"></div>
      </td>
    </tr>
  </tbody>
</table>

So you could probably use the candidate-votes-next-to-percent to get this value. e.g.:

require 'nokogiri'
require 'open-uri'
doc = Nokogiri::HTML(open("https://www.politico.com/2020-election/results/georgia/"))
votes = doc.css('tr[class*="candidate-row"]').map do |row|
  [
    row.css('div[class*="candidate-short-name"]').first.content,
    row.css('div[class*="candidate-votes-next-to-percent"]').first.content
  ]
end
# => [["Biden", "2,450,193"], ["Trump*", "2,448,635"]]

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top