我使用Mechanize加载了页面:
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所称的“ stray start tag”,当浏览器在现实生活中呈现页面时,它会被忽略(并且Firefox给了我忽略它的xpath),但是Nokogiri看不到任何多余的<tr>
。
有没有办法像这样清除悬挂标签的HTML?
在您的示例中为:
page.at '/html/body/tr/table'
但是也许这样做更有意义:
page.at 'table'
使用较简单的XPath查询?
found = page.at('//table')
您可以使用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
和at_xpath
,但我依靠at
除非我需要明确告诉Nokogiri我用作访问器的是CSS或XPath。这是一件方便的事。 Nokogiri的search
方法也是如此。