2009-09-30 7 views
9

का उपयोग कर एचटीएमएल दस्तावेज़ से स्ट्रिप टेक्स्ट रूबी, हैप्रिकॉट और नोकोगिरी का उपयोग करके दस्तावेज़ से एचटीएमएल टैग को कैसे छीनने के कई उदाहरण हैं आंतरिक_text विधियों में जो आपके लिए आसानी से और जल्दी से सभी HTML हटाते हैं।रूबी

जो मैं करने की कोशिश कर रहा हूं वह विपरीत है, HTML दस्तावेज़ से सभी पाठ हटा दें, केवल टैग और उनके गुणों को छोड़ दें।

मैंने दस्तावेज़ को आंतरिक_एचटीएमएल को शून्य में डालने पर विचार किया लेकिन फिर वास्तव में आपको इसे विपरीत में करना होगा क्योंकि पहले तत्व (रूट) में पूरे दस्तावेज़ के आंतरिक_एचटीएमएल हैं, तो आदर्श रूप में मेरे पास अंदरूनी अधिकांश तत्वों को शुरू करने के लिए और पूर्वजों के माध्यम से आगे बढ़ते समय भीतरी_एचटीएमएल को शून्य पर सेट करें।

क्या कोई इसे कुशलता से करने के लिए एक साफ छोटी सी चाल जानता है? मैं सोच रहा था कि शायद रेगेक्स की यह हो सकती है लेकिन शायद एचटीएमएल टोकननाइज़र/पार्सर के रूप में कुशलता से नहीं।

+0

क्या आपको खराब मार्कअप से निपटना होगा? (अनपेक्षित संस्थाएं, आदि) – Neall

+0

यह संभव है - मैं जिस मार्कअप को संसाधित कर रहा हूं वह अंतिम उपयोगकर्ताओं से आता है, इसलिए इस पर भरोसा नहीं किया जा सकता है। – davidsmalley

उत्तर

38

यह भी काम करता है:

doc = Nokogiri::HTML(your_html) 
doc.xpath("//text()").remove 
+1

बढ़िया! स्ट्रिंग प्राप्त करने के अंत में '.to_s' को टॉस करें और आप जाने के लिए अच्छे हैं! –

2

आप "टोकन" की एक सरणी बनाने के लिए स्ट्रिंग स्कैन कर सकते हैं, और उसके बाद ही उन है कि html टैग का चयन करें:

>> some_html 
=> "<div>foo bar</div><p>I like <em>this</em> stuff <a href='http://foo.bar'> long time</a></p>" 
>> some_html.scan(/<\/?[^>]+>|[\w\|`[email protected]#\$%^&*\(\)\-_\+=\[\]{}:;'",\.\/?]+|\s+/).select { |t| t =~ /<\/?[^>]+>/ }.join("") 
=> "<div></div><p><em></em><a href='http://foo.bar'></a></p>" 

== == संपादित

या और भी बेहतर, बस स्कैन एचटीएमएल टैग के लिए;)

>> some_html.scan(/<\/?[^>]+>/).join("") 
=> "<div></div><p><em></em><a href='http://foo.bar'></a></p>" 
3

एक टैग में नहीं सब कुछ हड़पने के लिए, आपको इस तरह nokogiri उपयोग कर सकते हैं:

doc.search('//text()').text 
बेशक

, कि <script> या <style> टैग की सामग्री की तरह सामान हड़पने जाएगा, ताकि आप भी काली सूची में डाले टैग हटा सकता है:

blacklist = ['title', 'script', 'style'] 
nodelist = doc.search('//text()') 
blacklist.each do |tag| 
    nodelist -= doc.search('//' + tag + '/text()') 
end 
nodelist.text 

अगर आपको पसंद किया श्वेत सूची में डालने सकता है, लेकिन है कि शायद और अधिक हो जायेगा समय-गहन:

whitelist = ['p', 'span', 'strong', 'i', 'b'] #The list goes on and on... 
nodelist = Nokogiri::XML::NodeSet.new(doc) 
whitelist.each do |tag| 
    nodelist += doc.search('//' + tag + '/text()') 
end 
nodelist.text 

आप एक विशाल XPath अभिव्यक्ति भी बना सकते हैं और एक खोज कर सकते हैं। मैं ईमानदारी से नहीं जानता कि किस तरह से तेज़ है, या यदि कोई सराहनीय अंतर भी है।

0

मैं सिर्फ इस के साथ आया था, लेकिन @ आंद्रे-आर के समाधान सू ज्यादा बेहतर है!

#!/usr/bin/env ruby 

require 'nokogiri' 

def strip_text doc 
    Nokogiri(doc).tap { |doc| 
    doc.traverse do |node| 
     node.content = nil if node.text? 
    end 
    }.to_s 
end 

require 'test/unit' 
require 'yaml' 
class TestHTMLStripping < Test::Unit::TestCase 
    def test_that_all_text_gets_strippped_from_the_document 
    dirty, clean = YAML.load DATA 
    assert_equal clean, strip_text(dirty) 
    end 
end 
__END__ 
--- 
- | 
    <!DOCTYPE html> 
    <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'> 
    <head> 
     <meta http-equiv='Content-type'  content='text/html; charset=UTF-8' /> 
     <title>Test HTML Document</title> 
     <meta http-equiv='content-language' content='en' /> 
    </head> 
    <body> 
     <h1>Test <abbr title='Hypertext Markup Language'>HTML</abbr> Document</h1> 
     <div class='main'> 
      <p> 
       <strong>Test</strong> <abbr title='Hypertext Markup Language'>HTML</abbr> <em>Document</em> 
      </p> 
     </div> 
    </body> 
    </html> 
- | 
    <!DOCTYPE html> 
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
    <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
    <title></title> 
    <meta http-equiv="content-language" content="en"> 
    </head> 
    <body><h1><abbr title="Hypertext Markup Language"></abbr></h1><div class="main"><p><strong></strong><abbr title="Hypertext Markup Language"></abbr><em></em></p></div></body> 
    </html>