gpt4 book ai didi

ruby - 用 Ruby 抓取并存储在哈希中

转载 作者:数据小太阳 更新时间:2023-10-29 08:09:59 26 4
gpt4 key购买 nike

我编写了 Ruby scraper 来从加利福尼亚州参议院获取竞选财务数据,然后将每个人保存为哈希。到目前为止,这是代码:

这是主要网站:http://cal-access.sos.ca.gov/Campaign/Candidates/

这是一个候选页面的例子:http://cal-access.sos.ca.gov/Campaign/Committees/Detail.aspx?id=1342974&session=2011&view=received

如果您想在代码中查看我的评论,这里是 github 存储库:https://github.com/aboutaaron/Baugh-For-Senate-2012/blob/master/final-exam.rb

关于代码...

require 'nokogiri'
require 'open-uri'

campaign_data = Nokogiri::HTML(open('http://cal-access.sos.ca.gov/Campaign/Candidates/'))

class Candidate
def initialize(url)
@url = url
@cal_access_url = "http://cal-access.sos.ca.gov"
@nodes = Nokogiri::HTML(open(@cal_access_url + @url))
end

def get_summary
candidate_page = @nodes

{
:political_party => candidate_page.css('span.hdr15').text,
:current_status => candidate_page.css('td tr:nth-child(2) td:nth-child(2) .txt7')[0].text,
:last_report_date => candidate_page.css('td tr:nth-child(3) td:nth-child(2) .txt7')[0].text,
:reporting_period => candidate_page.css('td tr:nth-child(4) td:nth-child(2) .txt7')[0].text,
:contributions_this_period => candidate_page.css('td tr:nth-child(5) td:nth-child(2) .txt7')[0].text.gsub(/[$,](?=\d)/, ''),
:total_contributions_this_period => candidate_page.css('td tr:nth-child(6) td:nth-child(2) .txt7')[0].text.gsub(/[$,](?=\d)/, ''),
:expenditures_this_period => candidate_page.css('td tr:nth-child(7) td:nth-child(2) .txt7')[0].text.gsub(/[$,](?=\d)/, ''),
:total_expenditures_this_period => candidate_page.css('td tr:nth-child(8) td:nth-child(2) .txt7')[0].text.gsub(/[$,](?=\d)/, ''),
:ending_cash => candidate_page.css('td tr:nth-child(9) td:nth-child(2) .txt7')[0].text.gsub(/[$,](?=\d)/, '')
}
end

def get_contributors
contributions_received = @nodes
grab_contributor_page = @nodes.css("a.sublink6")[0]['href']
contributor_page = Nokogiri::HTML(open(@cal_access_url + grab_contributor_page))
grab_contributions_page = contributor_page.css("a")[25]["href"]
contributions_received = Nokogiri::HTML(open(@cal_access_url + grab_contributions_page))
puts
puts "#{@cal_access_url}" + "#{grab_contributions_page}"
puts

contributions_received.css("table").reduce([]) do |memo, contributors|
begin

memo << {
:name_of_contributor => contributions_received.css("table:nth-child(57) tr:nth-child(2) td:nth-child(1) .txt7").text
}

rescue NoMethodError => e
puts e.message
puts "Error on #{contributors}"
end
memo
end
end

end

campaign_data.css('a.sublink2').each do |candidates|
puts "Just grabbed the page for " + candidates.text
candidate = Candidate.new(candidates["href"])
p candidate.get_summary
end

get_summary按计划工作。 get_contributors店铺第一投稿<td>按计划,但做了 20 多次。在我弄清楚多重打印问题之前,我现在只选择获取名称。

最终目标是对贡献者及其所需的所有信息进行哈希处理,并可能将它们转移到 SQL 数据库/Rails 应用程序中。但是,以前,我只想要一个可以工作的刮板。

有什么建议或指导吗?抱歉,如果代码不是 super 的。 super 编程新手。

最佳答案

你做得很好。在提供独立样本方面做得很好。您会惊讶于有多少人没有这样做。

我看到两个问题。

首先,并非所有页面都有您要查找的统计信息。这会使您的解析例程变得有些困惑。为了防止这种情况,您可以将其放入 get_summary:

return nil if candidate_page.text =~ /has not electronically filed/i

调用者在看到 nil 时应该做一些聪明的事情。

另一个问题是服务器有时响应不及时,导致脚本超时。如果您认为服务器对您的脚本发出请求的速度感到不安,您可以尝试添加一些 sleep 来减慢它的速度。或者,您可以添加重试循环。或者,您可以增加脚本超时所需的时间。

get_summary中也有一些重复的逻辑。此功能可能受益于策略与逻辑的分离。该策略是从页面检索哪些数据,以及如何格式化它:

FORMAT_MONEY = proc do |s|
s.gsub(/[$,](?=\d)/, '')
end

FIELDS = [
[:political_party, 'span.hdr15'],
[:current_status, 'td tr:nth-child(2) td:nth-child(2) .txt7'],
[:last_report_date, 'td tr:nth-child(3) td:nth-child(2) .txt7'],
[:reporting_period, 'td tr:nth-child(4) td:nth-child(2) .txt7'],
[:contributions_this_period, 'td tr:nth-child(5) td:nth-child(2) .txt7', FORMAT_MONEY],
[:total_contributions_this_period, 'td tr:nth-child(6) td:nth-child(2) .txt7', FORMAT_MONEY],
[:expenditures_this_period, 'td tr:nth-child(7) td:nth-child(2) .txt7', FORMAT_MONEY],
[:total_expenditures_this_period, 'td tr:nth-child(8) td:nth-child(2) .txt7', FORMAT_MONEY],
[:ending_cash, 'td tr:nth-child(9) td:nth-child(2) .txt7', FORMAT_MONEY],
]

实现是如何将该策略应用于 HTML 页面:

def get_summary
candidate_page = @nodes
return nil if candidate_page.text =~ /has not electronically filed/i
keys_and_values = FIELDS.map do |key, css_selector, format|
value = candidate_page.css(css_selector)[0].text
value = format[value] if format
[key, value]
end
Hash[keys_and_values]
end

关于ruby - 用 Ruby 抓取并存储在哈希中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11165918/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com