2017-01-26 14 views
-1

私はrubyで 'fingerprint' htmlページを、コンテンツではなく構造に基づいて探しています。アイデアは、指紋を参照コードと照合することによって、特定のページタイプの関心を特定することです。Ruby - HTML構造のフィンガープリンティング

私はよく仕事をしているようですが、(ヘキサ?)コードがどのように生成されたかについての手がかりはありません。

私はNokogiriを使って同様のものを生成しようとしましたが、その道を使って多くの進歩はありませんでした...どのような提案ですか?

ありがとうございます!

+1

これまでに書いたコードを表示してください。 –

+0

これは簡単ではありません。なぜなら、ブラウザがページをパーサーとは大きく異なる方法で扱うからです。ブラウザは表示用にレンダリングされ、要素はCSSとJavaScriptのために移動することができるので、視覚的に同じものはHTML自体とは大きく異なり、逆も同様です。Nokogiriは生のHTMLを見るので、レイアウトに動的に影響する違いを見つける方法を伝えなければなりません。 WATIRなどのツールを使用すると、レンダリングされたページ内の領域を類似性をチェックすることができます。 –

答えて

1

私はそれが簡単な問題だと考えていますの後にパーザがそれを見たのに対してブラウザはJavaScriptとAJAXを持つページを描画し、バックエンドはいくつかの基準に基づいて異なるマークアップを送信しますそれはHTMLにはありません。ここでは、言った

は、私は指紋を生成するために使用したい基本的な考え方です:

スクリプトが異なるページビーイングその結果、異なる可能性があり
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" 

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が取り除かれ、ページが大幅に異なる可能性はありますが、ページは同じであるように見えます。

私はそれを正確かつ確実に行うために唯一の方法は、ブラウザを使用してページをレンダリングし、ページ上のテキストを探すことを可能にするWATIRのようなものを使用することです。

+0

あなたが遅れて帰ってくれて申し訳ありません - js/ajaxなどのために基本構造の弾丸証明を作るのは難しいと完全に同意しますが、プレレンダリングはそれに対処します。 SAXの提案のために、あなたとGSPのおかげで本当に良いスタートです。 – user1051849

1

構造によって、属性を持たずテキストも含まないタグを意味するだけですか?

Nokogiri(または他の場所)から入手可能なSAXパーサーを試すことができます。 XMLパーサーには、完全なXML構造を構築する主なタイプと、ファイルを線形時間に解析し、イベントを発生させるイベントベースのパーサーという2種類のXMLパーサーがあります。それがSAXパーサーの仕組みです。

鋸山のコード例は、良好な出発点である:http://www.rubydoc.info/gems/nokogiri/Nokogiri/HTML/SAX/Parser

、それらが発生したとして、次のコードは、タグ名の配列を構築します。

のようなドキュメントを開始すると仮定すると、
# 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])) 

:あなたのパーサの出力は

parser.tags # => [ 'html', 'head', 'body', 'p', 'strong' ] 

EDITのようなものかもしれません

<html><head></head><body><p>This is a <strong>test</strong></p></body></html> 

:でHTMLのSAXパーサーを使用するには答えを修正純粋なXMLパーサーではなくHTMLエラー訂正(http://www.rubydoc.info/gems/nokogiri/Nokogiri/XML/SAX/Parser

+0

タグをカウントする際の問題は、ページレイアウトのアイデアを得るために、ドキュメント内の位置を取得する必要があることです。ページ内の要素を移動すると、タグをカウントするコードをばかげているが、要素の位置も追跡するコードを欺くことはありません。また、いくつかのページは異なるテキストのテンプレートなので、タグの数と場所は役に立ちません。テキストをハッシュする必要もあります。しかし、CSSやJavaScriptが関わっている場合、ページは完全に違って見えるかもしれませんが、HTMLレイアウトは同じです。 –

+0

上記のSAXパーサーは、配列にタグ名を順番に追加します。タグを数えるだけではありません。また、私はテキストについてあなたに同意しますが、質問はコンテンツを除外するよう明示しました。私はそれを無視してテキストを意味するようにしました。 – GSP