如何使用Nokogiri删除ActiveSupport的“starts_with”的HTTP链接?

时间:2011-05-07 15:30:57

标签: ruby-on-rails ruby nokogiri

当我尝试这个时:

item.css("a").each do |a|
  if !a.starts_with? 'http://'
     a.replace a.content
  end
end

我明白了:

NoMethodError: undefined method 'starts_with?' for #<Nokogiri::XML::Element:0x1b48a60> 

编辑:

当然有一种更清洁的方式,但这似乎有效。

item.css("a").each do |a|
  unless a["href"].blank?
    if !a["href"].starts_with? 'http://' 
      a.replace a.content
    end
  end
end

2 个答案:

答案 0 :(得分:1)

问题是你试图在没有实现它的对象上使用starts_with方法。

item.css("a").each do |a|

将返回a中的XML节点。那些属于Nokogiri。你想要做的是将节点转换为文本,但只转换你要检查的部分,因为它是节点的参数,可以像这样访问:

a['href']

所以,你想使用这样的东西:

item.css("a").each do |a|
  if !(a.starts_with?['href']('http://'))
     a.replace(a.content)
  end
end

这样做的缺点是你必须遍历文档中的每个<a>标记,这可能会在包含大量链接的大页面上变慢。

另一种方法是使用XPath的starts-with函数:

require 'nokogiri'

item = Nokogiri::HTML('<a href="doesnt_start_with">foo</a><a href="http://bar">bar</a>')
puts item.to_html

输出:

>> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
>> <html><body>
>> <a href="doesnt_start_with">foo</a><a href="http://bar">bar</a>
>> </body></html>

以下是使用XPath的方法:

item.search('//a[not(starts-with(@href, "http://"))]').each do |a|
  a.replace(a.content)
end
puts item.to_html

哪个输出:

>> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
>> <html><body>foo<a href="http://bar">bar</a>
>> </body></html>

使用XPath查找节点的好处是它都在编译的C中运行,而不是让Ruby这样做。

答案 1 :(得分:0)

该方法不应该是start_with?