Ruby 使用Nokogiri和需要JSON输出的刮表
因此,我有一个包含多行和多列的表Ruby 使用Nokogiri和需要JSON输出的刮表,ruby,screen-scraping,nokogiri,watir,page-object-gem,Ruby,Screen Scraping,Nokogiri,Watir,Page Object Gem,因此,我有一个包含多行和多列的表 <table> <tr> <th>Employee Name</th> <th>Reg Hours</th> <th>OT Hours</th> </tr> <tr> <td>Employee 1</td> <td>10</td> <
<table>
<tr>
<th>Employee Name</th>
<th>Reg Hours</th>
<th>OT Hours</th>
</tr>
<tr>
<td>Employee 1</td>
<td>10</td>
<td>20</td>
</tr>
<tr>
<td>Employee 2</td>
<td>5</td>
<td>10</td>
</tr>
</table>
编辑:
使用页面对象gem和@Dave_McNulla的链接,我尝试了这段代码,只是想看看我得到了什么:
class MyPage
include PageObject
table(:report, :id => 'UC255_tblSummary')
def get_some_information
report_element[1][2].text
end
end
puts get_some_information
但是,什么也没有归还
数据:
有一份工时表的副本。第一个很好。需要的另一个表是附件收入表。(我还需要activations表,但我将尝试从合并小时和附件收入表的代码中合并该表。我认为一般方法是:
#I assume you would have a better way to identify the tables than by index
hours_table = browser.table(:index, 0)
wage_table = browser.table(:index, 1)
#Turn the tables into a hash
employee_hours = {}
hours_table.trs.drop(1).each do |tr|
tds = tr.tds
employee_hours[ tds[0].text ] = {"Reg Hours" => tds[1].text, "OT Hours" => tds[2].text}
end
#=> {"Employee 1"=>{"Reg Hours"=>"10", "OT Hours"=>"20"}, "Employee 2"=>{"Reg Hours"=>"5", "OT Hours"=>"10"}}
employee_wage = {}
wage_table.trs.drop(1).each do |tr|
tds = tr.tds
employee_wage[ tds[0].text ] = {"Revenue" => tds[1].text}
end
#=> {"Employee 2"=>{"Revenue"=>"$10"}, "Employee 1"=>{"Revenue"=>"$50"}}
诺科吉里:
page = Nokogiri::HTML.parse(browser.html)
hours_table = page.search('table')[0]
wage_table = page.search('table')[1]
employee_hours = {}
hours_table.search('tr').drop(1).each do |tr|
tds = tr.search('td')
employee_hours[ tds[0].text ] = {"Reg Hours" => tds[1].text, "OT Hours" => tds[2].text}
end
#=> {"Employee 1"=>{"Reg Hours"=>"10", "OT Hours"=>"20"}, "Employee 2"=>{"Reg Hours"=>"5", "OT Hours"=>"10"}}
employee_wage = {}
wage_table.search('tr').drop(1).each do |tr|
tds = tr.search('td')
employee_wage[ tds[0].text ] = {"Revenue" => tds[1].text}
end
#=> {"Employee 2"=>{"Revenue"=>"$10"}, "Employee 1"=>{"Revenue"=>"$50"}}
将两个表的结果合并在一起
您希望将这两个哈希合并在一起,以便对于特定员工,哈希将包括他们的工作时间和收入
employee = employee_hours.merge(employee_wage){ |key, old, new| new.merge(old) }
#=> {"Employee 1"=>{"Revenue"=>"$50", "Reg Hours"=>"10", "OT Hours"=>"20"}, "Employee 2"=>{"Revenue"=>"$10", "Reg Hours"=>"5", "OT Hours"=>"10"}}
转换为JSON
基于此,您可以将哈希转换为json
require 'json'
employee.to_json
我认为一般的做法是:
#I assume you would have a better way to identify the tables than by index
hours_table = browser.table(:index, 0)
wage_table = browser.table(:index, 1)
#Turn the tables into a hash
employee_hours = {}
hours_table.trs.drop(1).each do |tr|
tds = tr.tds
employee_hours[ tds[0].text ] = {"Reg Hours" => tds[1].text, "OT Hours" => tds[2].text}
end
#=> {"Employee 1"=>{"Reg Hours"=>"10", "OT Hours"=>"20"}, "Employee 2"=>{"Reg Hours"=>"5", "OT Hours"=>"10"}}
employee_wage = {}
wage_table.trs.drop(1).each do |tr|
tds = tr.tds
employee_wage[ tds[0].text ] = {"Revenue" => tds[1].text}
end
#=> {"Employee 2"=>{"Revenue"=>"$10"}, "Employee 1"=>{"Revenue"=>"$50"}}
诺科吉里:
page = Nokogiri::HTML.parse(browser.html)
hours_table = page.search('table')[0]
wage_table = page.search('table')[1]
employee_hours = {}
hours_table.search('tr').drop(1).each do |tr|
tds = tr.search('td')
employee_hours[ tds[0].text ] = {"Reg Hours" => tds[1].text, "OT Hours" => tds[2].text}
end
#=> {"Employee 1"=>{"Reg Hours"=>"10", "OT Hours"=>"20"}, "Employee 2"=>{"Reg Hours"=>"5", "OT Hours"=>"10"}}
employee_wage = {}
wage_table.search('tr').drop(1).each do |tr|
tds = tr.search('td')
employee_wage[ tds[0].text ] = {"Revenue" => tds[1].text}
end
#=> {"Employee 2"=>{"Revenue"=>"$10"}, "Employee 1"=>{"Revenue"=>"$50"}}
将两个表的结果合并在一起
您希望将这两个哈希合并在一起,以便对于特定员工,哈希将包括他们的工作时间和收入
employee = employee_hours.merge(employee_wage){ |key, old, new| new.merge(old) }
#=> {"Employee 1"=>{"Revenue"=>"$50", "Reg Hours"=>"10", "OT Hours"=>"20"}, "Employee 2"=>{"Revenue"=>"$10", "Reg Hours"=>"5", "OT Hours"=>"10"}}
转换为JSON
基于此,您可以将哈希转换为json
require 'json'
employee.to_json
您可以修改HTML以包含表元素的类吗?具体来说,标记可以有一个“employee”类,每个标记可以有一个类来表示它是什么(例如“name”、“revenue”等)这将帮助您匹配员工姓名,然后在另一个HTML文档中找到它,然后从这两个文档中构建JSON,或者在构建对象之前将它们合并在一起。HTML不是我的。获取xpath节点不是问题……我想我更多地停留在Ruby部分。我不确定如何迭代行并合并数据在这两个表之间。你想使用Nokogiri而不是Watir有什么原因吗?Cheezy/Jeff Morgan在页面对象中有一种从表中获取信息的方法:@JustinKo,Watir能做我需要做的吗?我在文档中找不到任何东西。你能修改HTML以包含表元素的类吗?特别是,标记可以有一个“employee”类和每个标记可以有一个类来表示它是什么(例如“名称”、“收入”等)这将帮助您匹配员工姓名,然后在另一个HTML文档中找到它,然后从这两个文档中构建JSON,或者在构建对象之前将它们合并在一起。HTML不是我的。获取xpath节点不是问题……我想我更多地停留在Ruby部分。我不确定如何迭代行并合并数据在这两个表之间。你为什么要使用Nokogiri而不是Watir?Cheezy/Jeff Morgan在页面对象中有一种从表中获取信息的方法:@JustinKo,Watir可以做我需要做的事情吗?我在文档中找不到任何东西。谢谢你的回复。我做了以下更改:hours_table=browser.tr(:xpath,//*[@id=“tblReportItems”]/tbody/tr[1]”),因为表ID现在似乎已消失。获取“未定义的方法哈希”错误不过,现在,从water webdriver开始,
hash
是为表而不是trs定义的。换句话说,您需要确保hours\u table
仍然是一个表。根据建议的更改,您应该能够执行hours\u table=browser.table(:id=>tblReportItems'))
。我明白了……但该表ID用于一个包罗万象的表。我需要的表在该表中(没有ID)。尝试您的nokogiri示例,我得到一个“text”的未定义方法错误。您是否更改了hours\u table
和wage\u table
以指向正确的表?这两个解决方案都硬编码到页面上的第一个/第二个表中。您需要更新它们以处理特定的表(因为我不知道你的页面的html是什么样子)。我知道了;我需要的表分别是第五个和第六个。但是我仍然收到“text”的“no method”错误。谢谢你的回复。我做了以下更改:hours_table=browser.tr(:xpath,“/*[@id=“tblReportItems”]/tbody/tr[1])因为表ID现在似乎已消失。获取“未定义的方法'哈希'错误”不过,现在,从water webdriver开始,hash
是为表而不是trs定义的。换句话说,您需要确保hours\u table
仍然是一个表。根据建议的更改,您应该能够执行hours\u table=browser.table(:id=>tblReportItems'))
。我明白了……但该表ID用于一个包罗万象的表。我需要的表在该表中(没有ID)。尝试您的nokogiri示例,我得到一个“text”的未定义方法错误。您是否更改了hours\u table
和wage\u table
以指向正确的表?这两个解决方案都硬编码到页面上的第一个/第二个表中。您需要更新它们以处理特定的表(因为我不知道你的页面的html是什么样子的)。我知道了;我需要的表分别是第五个和第六个。不过,我仍然得到了“text”的“no method”错误。