我正在为一些汽车经销商的库存管理器重新格式化搜索查询的HTML输出。没有直接的数据库访问,服务创建者没有可用的信息,因此我决定尝试使用Nokogiri解析和重新格式化数据,并根据搜索查询生成新的结果页面。
首次加载页面时,我只是使用默认搜索来生成第一个结果。
为了使搜索起作用,我将查询发送到这样的URL:
post '/search/?:search_query' do
url = "http://domain.com/v/?DealerId=" + settings.dealer_id + "&maxrows=10&#{params[:search_query]}"
doc = Nokogiri::HTML(open(url))
doc.css("td:nth-child(5) .ForeColor4").each do |msrp|
session["msrp"] = msrp.inner_html
end
doc.css("td:nth-child(4) .ForeColor4").each do |price|
session["price"] = price.inner_html
end
erb :index
end
我知道必须有一个更聪明的方法来做到这一点。
编辑:
请求数据的示例网址:
http://domain.com/?DealerId=1234&object=list&lang=en&MAKE=&MODEL=&maxrows=50&MinYear=&MaxYear=2011&Type=N&MinPrice=&MaxPrice=&STYLE=&ExtColor=&MaxMiles=&StockNo=
生成的HTML的说明:
不幸的是,它的旧代码几乎完全基于表格,具有内联样式,并且在大多数区域中缺少类或ID。
CSS选择器的一个示例:
td:nth-child(5) .ForeColor4
XPath选择器:
//td[(((count(preceding-sibling::*) + 1) = 5) and parent::*)]//*[contains(concat( " ", @class, " " ), concat( " ", "ForeColor4", " " ))]
我也把机械化或hpricot视为可能,但我不知道最好的工具,因为我之前没有尝试过屏幕抓取。
摘要:我想从HTML中提取数据,暂时将其存储在变量/ session / cookie中(数据每天更改几次),然后能够将输出重新格式化为我自己的HTML / CSS样式。
答案 0 :(得分:1)
就个人而言,我会将刮擦与用户操作分开。有一个独立的过程刮擦并填充您的数据库。这将极大地提高性能,因为提取,创建DOM,解析,然后在每个动作上呈现输出都会变慢。
答案 1 :(得分:0)
doc.css("td:nth-child(5) .ForeColor4").each do |msrp| session["msrp"] = msrp.inner_html end doc.css("td:nth-child(4) .ForeColor4").each do |price| session["price"] = price.inner_html end
您可能希望使用Nokogiri的at_css()
方法而不是常规css()
。 at_css()
找到目标的第一个匹配项,并且只返回一个节点,类似于对.first
返回的节点集执行.css()
。
这会简化您对此表单的查找:
session["msrp"] = doc.at_css("td:nth-child(5) .ForeColor4").inner_html
我可能会在测试结束时添加类似rescue 'msrp lookup failed'
的内容,以防万一你有不好的访问者。或者,当inner_html()
试图从零读取时,你可以让代码失败。这只是一种更友好的调试方式。
否则你的查找似乎不错。