1

我已经在 Ruby 中看到了基于白名单的 HTML 消毒剂,但我需要相反的情况,我只需要从页面中删除链接即可准备好进行 PDF 转换。我尝试了 Sanitize,但它不符合我的需要,因为很难猜测在获取的页面上将使用哪些 HTML 元素,以便我可以将它们添加到列表中。

如果我的输入是

<a href="link">Link!</a>
<b>Bold Text</b>
<div>A div!</div>

我想要

Link!
<b>Bold Text</b>
<div>A div!</div>

成为输出。

Ruby 是否有任何“基于黑名单的消毒剂”?

4

4 回答 4

2

您需要一个 HTML 解析器,例如Nokogiri。它允许您浏览文档,搜索特定节点(“标签”)并对它们执行操作:

require 'nokogiri'

html = '<a href="link">Link!</a>
<b>Bold Text</b>
<div>A div!</div>
'

doc = Nokogiri.HTML(html)

doc.search('a').each do |a|
  a.replace(a.content)
end

puts doc.to_html

结果是:

<html><body>Link!
<b>Bold Text</b>
<div>A div!</div>
</body></html>

请注意,Nokogiri 对代码进行了一些修复,提供了适当的<html><body>标签。它不必这样做,我可以告诉它使用并返回一个文档片段,但通常我们让它做它的事情。

于 2012-11-10T05:10:41.857 回答
1

铁皮人的回答略有不同,仍然使用Nokogiri

require 'nokogiri' # gem install nokogiri
doc = Nokogiri.HTML( my_html )
doc.css('a,blink,marquee').each do |el|
  el.replace( el.inner_html )
end
cleaned = doc.to_html

这里的两个区别是:

  1. 使用cssoversearch可以更具体地了解所使用的选择器(尽管它没有提供功能差异),但更重要的是

  2. 通过替换,inner_html我们保留了链接内可能的标记。例如,给定标记:

    <p><a href="foo">Hi <b>Mom</b></a>!</p>
    

    然后替换为.content会产生:

    <p>Hi Mom!</p>
    

    而替换为.inner_html产生:

    <p>Hi <b>Mom</b>!</p>
    
于 2012-11-10T05:20:01.770 回答
1

Rails 4.2 可以开箱即用地做到这一点。对于旧版本gem 'rails-html-sanitizer'是必需的

仅将提供的标签和属性列入白名单

white_list_sanitizer = Rails::Html::WhiteListSanitizer.new
white_list_sanitizer.sanitize(@article.body, tags: %w(table tr td), attributes: %w(id class style))

或使用丝瓜络的 TargetScrubber

Rails::Html::TargetScrubber

PermitScrubber 挑选出允许清理的标签和属性,Rails::Html::TargetScrubber 将它们作为删除目标。

scrubber = Rails::Html::TargetScrubber.new
scrubber.tags = ['img']

html_fragment = Loofah.fragment('<a><img/ ></a>')
html_fragment.scrub!(scrubber)
html_fragment.to_s # => "<a></a>"

Rails HTML 清理器

于 2015-05-11T10:55:54.793 回答
0
html_without_links = remove_tags("<a href="link">Link!</a><b>Bold Text</b><div>A div!</div>",'a')

你可以使用上面的方法和下面的代码,你应该得到你想要的。

require 'nokogiri'

def is_html?(text)
  stripped_text = Nokogiri::HTML(text).text.strip
  return !stripped_text.eql?(text)
end

def remove_tags(message_string,tag=nil)
  return message_string if message_string.blank? || tag.blank? || !is_html?(message_string)
  html_doc = Nokogiri.HTML(message_string)
  html_doc.search(tag).each do |a|
    a.replace(a.content)
  end

  html_doc.text
end
于 2017-01-18T18:15:51.627 回答