【问题标题】:Strip style attributes with nokogiri使用 nokogiri 去除样式属性
【发布时间】:2011-08-31 01:54:36
【问题描述】:

我正在用 nokogiri 抓取一个 html 页面,我想去掉所有样式属性。
我怎样才能做到这一点? (我没有使用 Rails,所以我不能使用它的 sanitize 方法,我不想使用 sanitize gem,因为我想将黑名单删除而不是白名单)

html = open(url)
doc = Nokogiri::HTML(html.read)
doc.css('.post').each do |post|
puts post.to_s
end

=> <p><span style="font-size: x-large">bla bla <a href="http://torrentfreak.com/netflix-is-killing-bittorrent-in-the-us-110427/">statistica</a> blabla</span></p>

我希望它是

=> <p><span>bla bla <a href="http://torrentfreak.com/netflix-is-killing-bittorrent-in-the-us-110427/">statistica</a> blabla</span></p>

【问题讨论】:

    标签: html nokogiri sanitize


    【解决方案1】:
    require 'nokogiri'
    
    html = '<p class="post"><span style="font-size: x-large">bla bla</span></p>'
    doc = Nokogiri::HTML(html)
    doc.xpath('//@style').remove
    puts doc.css('.post')
    #=> <p class="post"><span>bla bla</span></p>
    

    编辑显示您可以只调用NodeSet#remove 而不必使用.each(&amp;:remove)

    请注意,如果您有 DocumentFragment 而不是 Document,则 Nokogiri 有a longstanding bug,从片段中搜索不会像您预期的那样工作。解决方法是使用:

    doc.xpath('@style|.//@style').remove
    

    【讨论】:

    • 使用doc.xpath('.//@style').remove 删除所有节点的所有内联样式,注意@bricker 开头提到的.。链 .to_s 以获取生成的 html 字符串。
    • 更正:不要链接它,而是使用 description.to_s 来获取生成的 html 字符串。如果您不想要DOCTYPE,您应该改用Nokogiri::HTML.fragment 方法,请参阅stackoverflow.com/questions/4723344/…
    【解决方案2】:

    这适用于文档和文档片段:

    doc = Nokogiri::HTML::DocumentFragment.parse(...)
    

    doc = Nokogiri::HTML(...)
    

    要删除所有的'style'属性,你可以做一个

    doc.css('*').remove_attr('style')
    

    【讨论】:

      【解决方案3】:

      我尝试了 Phrogz 的答案,但无法让它工作(虽然我使用的是文档片段,但我认为它应该也能工作?)。

      开头的“//”似乎并没有像我预期的那样检查所有节点。最后我做了一些更冗长的事情,但它奏效了,所以在这里记录一下,以防其他人有同样的麻烦是我的解决方案(虽然它很脏):

      doc = Nokogiri::HTML::Document.new
      body_dom = doc.fragment( my_html )
      
      # strip out any attributes we don't want
      body_dom.xpath( './/*[@align]|*[@align]' ).each do |tag|
          tag.attributes["align"].remove
      end
      

      【讨论】:

      • 这也可能有效:body_dom.xpath('.//@class')(注意 xpath 开头的额外点)
      • Nokogiri 和/或 LibXML2 有 a bug with XPath inside fragments。正如您所指出的,当前片段的最佳解决方法是:您必须使用 foo|.//foo 而不是 //foo
      猜你喜欢
      • 1970-01-01
      • 2013-08-23
      • 2019-07-30
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多