1

我使用机械化加载了一个页面:

url = 'http://www.blah.com'
agent = Mechanize.new
page = agent.get(url)

并尝试使用 XPath 选择器访问元素:

found = page.at('/html/body/table')

它返回nil是因为我无法控制的 HTML 有一个不应该出现的开始标签:

<html>
  <body>
    <tr>
    <table>
      . . .

当浏览器在现实生活中呈现页面时,Firefox 称之为“流浪开始标记”,它会被忽略(并且 Firefox 给了我忽略它的 xpaths),但是 Nokogiri 看不到任何超出这个额外的<tr>.

有没有办法像这样清理悬挂标签的HTML?

4

3 回答 3

2

使用不那么脆弱的 XPath 查询?

found = page.at('//table')
于 2012-10-10T15:38:59.850 回答
2

在您的示例中,它将是:

page.at '/html/body/tr/table'

但也许这样做更有意义:

page.at 'table'
于 2012-10-09T03:57:48.800 回答
0

您可以使用 Nokogiri 轻松清洁它:

require 'nokogiri'

html = '<html><body><tr><table><tr><td>foo</td></tr></table></tr></body></html>'
doc = Nokogiri::HTML(html)

inner_table = doc.at('//body/tr/table')
if (inner_table)
  doc.at('body tr').replace(inner_table)
end

puts doc.to_html

结果是:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><table><tr><td>foo</td></tr></table></body></html>

如果您的 HTML 更复杂,则找到某种类似于<body><tr><table>节点链的标记,并将其替换为上面的代码。

请注意,我混合了 XPath 和 CSS 访问器。我更喜欢 CSS 的可读性,但有时 XPath 更容易获得某些东西,或者更能自我记录。

另请注意,我在 Nokogiri 的at方法中同时使用了 XPath 和 CSS。尽管 Nokogiri 支持at,at_css和,但除非我需要明确告诉 Nokogiri 我使用的访问器是 CSS 或 XPath ,否则我at_xpath依赖它。at这是一个方便的事情。这同样适用于 Nokogiri 的search方法。

于 2012-10-10T16:23:58.277 回答