我在抓取html表格时遇到问题。 这是链接: https://www.basketball-reference.com/players/c/curryst01/gamelog/2016 (是的,这是一个著名的Ruby抓取入门教程(。 这是相关的代码:
doc = Nokogiri::HTML.parse(open(link))
# Get the biggest table
big_table = doc.css("table").sort { |x,y| y.css("tr").count <=> x.css("tr").count }.first
# Number of rows is 87, but there are 5 heads that I wanna remove
big_table.css("tr").count
# This doesn't remove heads
big_table = big_table.select { |row| row.css("th").empty? }
事实上,在 HTML 中(我对 HTML 一无所知,我从 4h 开始就使用 Ruby(th 是标题的标签,td 是标准单元格的标签,tr 只是一行。 目标是删除标头,因此如果节点集(nodeset 就像标签的内容?(为空,则.empty
返回,最后一行代码应该只返回 tr 元素。 但它不起作用,实际上结果是 [] .
相反,我注意到:big_table.select{|row| row.css("td").empty?}.count
等于 5 ... 所以,我决定做:
big_table = big_table.select{|row| row.css("td").any?}
而且效果很好...
我的问题是:为什么这条线有效?为什么第一次尝试失败了? 也许是我缺少的HTML结构中的东西...
谢谢!
让我们来看看big_table
> big_table.class
=> Nokogiri::XML::NodeSet
> big_table.size
=> 1
所以首先,对big_table
做Enumerable#select
可能没有做你所期望的。相反,如果您捕获行:
> rows = big_table.css("tr")
> rows.count
=> 87
现在,您可以在行上执行select
。让我们取一行任意行,看看它包含什么:
> rows[2].css("td").count
=> 29
> rows[2].css("th").count
=> 1
因此,典型的行有 29 个td
元素和一个th
。事实上,每一行都至少有一个th
,这就是为什么css("th").empty?
什么也没返回。相反,全标题行不包含任何td
元素,这就是您尝试的方法有效的原因。