首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby - HTML结构指纹图谱

Ruby - HTML结构指纹图谱
EN

Stack Overflow用户
提问于 2017-01-26 13:22:31
回答 2查看 77关注 0票数 0

我正在寻找一种方法,在红宝石‘指纹’html页面的结构,而不是他们的内容。其思想是通过将特定页面类型的指纹与参考代码匹配来识别特定的感兴趣的页面类型。

我发现了 (相当老的)工具,它似乎做得很好,但没有给出关于(十六进制?)生成代码。

我试过使用Nokogiri来产生类似的东西,但是使用这个方法没有取得多大进展.有什么建议吗?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-26 20:10:46

我不认为这是一个简单的问题,因为在解析器看到文档与浏览器呈现包含JavaScript和AJAX的页面以及后端根据HTML中不存在的条件发送不同的标记之后,文档可能会发生很多变化。

这就是说,我用来生成指纹的基本想法是:

代码语言:javascript
复制
require 'digest'
require 'nokogiri'

doc1 = Nokogiri::HTML.parse(<<EOT)
<html>
  <body>
    <div class='foo'><p>content</p></div>
    <div class='bar'><p>content</p></div>
  </body>
</html>
EOT

doc2 = Nokogiri::HTML.parse(<<EOT)
<html>
  <body>
    <div class='bar'><p>content</p></div>
    <div class='foo'><p>content</p></div>
  </body>
</html>
EOT

[doc1, doc2].each { |d| d.search('//text()').remove }
Digest::MD5.hexdigest(doc1.to_html) # => "3abe6e365f145452a5c99a38bfdf2339"
Digest::MD5.hexdigest(doc2.to_html) # => "25c4c66fa90c683cc2d3ce1e7e6a461b"

将其与以下情况进行比较:

代码语言:javascript
复制
require 'digest'
require 'nokogiri'

doc1 = Nokogiri::HTML.parse(<<EOT)
<html>
  <head>
    <script>
      // a script
    </script>
  </head>
  <body>
    <div class='foo'><p>content</p></div>
    <div class='bar'><p>content</p></div>
  </body>
</html>
EOT

doc2 = Nokogiri::HTML.parse(<<EOT)
<html>
  <head>
    <script>
      // a different script
    </script>
  </head>
  <body>
    <div class='foo'><p>content</p></div>
    <div class='bar'><p>content</p></div>
  </body>
</html>
EOT

[doc1, doc2].each { |d| d.search('//text()').remove }
Digest::MD5.hexdigest(doc1.to_html) # => "13215fefd8efe06268574eaa82f4c765"
Digest::MD5.hexdigest(doc2.to_html) # => "13215fefd8efe06268574eaa82f4c765"

其中脚本可能是不同的,从而导致呈现不同的页面。剥离内容将去掉JavaScript,使页面看起来是相同的,尽管它们可能有很大的不同。

我认为准确可靠地这样做的唯一方法是使用类似于WATIR的东西,它使用浏览器呈现页面,然后允许您在页面上查找文本。

票数 2
EN

Stack Overflow用户

发布于 2017-01-26 13:44:32

在结构上,您只是指没有属性和文本的标记吗?

您可以尝试通过Nokogiri (或其他地方)提供的SAX解析器。XML解析器有两种主要类型:构建完整XML结构的解析器和基于事件的解析器,该解析器以线性时间解析文件,并在文件进入和离开元素时触发事件。这就是SAX解析器的工作方式。

Nokogiri中的示例代码是一个很好的起点:http://www.rubydoc.info/gems/nokogiri/Nokogiri/HTML/SAX/Parser

下面的代码在遇到标记名时会生成它们的数组。

代码语言:javascript
复制
# Build a list of tags.
class MyDoc < Nokogiri::XML::SAX::Document
  attr_accessor :tags

  def start_element name, attrs = []
    tags << name
  end

  def end_element name
    # NOOP
  end
end

# Create our parser
parser = Nokogiri::HTML::SAX::Parser.new(MyDoc.new)
parser.tags = []

# Send some XML to the parser
parser.parse(File.open(ARGV[0]))

假设您从这样的文档开始:

代码语言:javascript
复制
<html><head></head><body><p>This is a <strong>test</strong></p></body></html>

解析器的输出可能类似于

代码语言:javascript
复制
parser.tags # => [ 'html', 'head', 'body', 'p', 'strong' ]

编辑:修改答案,使用HTML解析器进行HTML错误更正,而不是使用纯XML解析器( http://www.rubydoc.info/gems/nokogiri/Nokogiri/XML/SAX/Parser )。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41874442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档