有没有更好的方法可以使用Nokogiri提取网页上的可见文本?目前我使用的是inner_text
方法,但是该方法将许多JavaScript视为可见文本。我想捕捉的唯一文本是屏幕上可见的文本。
例如,在IRB中,如果我在Ruby 1.9.2-p290中执行以下操作:
require 'nokogiri'
require 'open-uri'
doc = Nokogiri::HTML(open("http://www.bodybuilding.com/store/catalog/new-products.jsp?addFacet=REF_BRAND:BRAND_MET_RX"))
words = doc.inner_text
words.scan(/w+/)
如果我搜索单词"function",我会发现它在列表中出现了20次,但是如果我转到http://www.bodybuilding.com/store/catalog/new-products.jsp?addFacet=REF_BRAND:BRAND_MET_RX单词"function"不会出现在可见文本中的任何位置。
我可以忽略JavaScript吗?或者有更好的方法吗?
您可以尝试:
require 'nokogiri'
require 'open-uri'
doc = Nokogiri::HTML(open("http://www.bodybuilding.com/store/catalog/new-products.jsp?addFacet=REF_BRAND:BRAND_MET_RX"))
doc.traverse{ |x|
if x.text? && x.text !~ /^s*$/
puts x.text
end
}
我对Nokogiri做得不多,但我相信这应该可以找到/输出文档中所有非空白的文本节点。这似乎至少忽略了javascript,我检查的所有文本都在页面上可见(尽管其中一些在下拉菜单中)。
您可以忽略JavaScript,还有更好的方法。你忽视了野村的力量。非常
与其给你提供直接的答案,不如学着用Nokogiri"钓鱼"。
在类似的文档中
<html>
<body>
<p>foo</p>
<p>bar</p>
</body>
</html>
我建议从CSS访问者开始,因为人们通常更熟悉它们:
- CCD_ 2将解析并返回CCD_ 3中的HTML DOM
doc.at('p')
将返回一个Node,该Node基本上指向第一个<p>
节点doc.search('p')
将返回所有匹配节点的NodeSet,其作用类似于数组,在本例中为所有<p>
节点doc.at('p').text
将返回节点内的文本doc.search('p').map{ |n| n.text }
将返回<p>
节点中的所有文本作为文本字符串数组
随着文档变得越来越复杂,您需要深入查看。有时您可以使用CSS访问器(如'body p'
或类似的访问器)来完成此操作,有时您需要使用XPaths。我不想谈这些,但有很棒的教程和参考资料。
野村的教程非常好。仔细阅读它们,它们会揭示你需要知道的一切。
此外,在Stack Overflow上还有许多关于讨论这类问题的答案。查看页面右侧的"相关"链接。
忽略JavaScript所在的标签(<script>
)。当我们在做的时候,我们也应该忽略CSS(<styles>
)。
require 'nokogiri'
require 'open-uri'
doc = Nokogiri::HTML(URI.open("http://www.bodybuilding.com/store/catalog/new-products.jsp?addFacet=REF_BRAND:BRAND_MET_RX"))
doc.css('style').each(&:remove)
doc.css('script').each(&:remove)
puts doc.text
# Alternatively, for cleaner output:
# puts doc.text.split("n").map(&:strip).reject(&:empty?)