Fáb*_*rez 11 ruby regex string nokogiri
我正在尝试使用Ruby检索网页的每个外部链接.我正在使用String.scan这个正则表达式:
/href="https?:[^"]*|href='https?:[^']*/i
Run Code Online (Sandbox Code Playgroud)
然后,我可以使用gsub删除href部分:
str.gsub(/href=['"]/)
Run Code Online (Sandbox Code Playgroud)
这很好用,但我不确定它在性能方面是否有效.这可以使用,或者我应该使用更具体的解析器(例如nokogiri)?哪种方式更好?
谢谢!
tok*_*and 16
使用正则表达式适用于快速而脏的脚本,但Nokogiri使用起来非常简单:
require 'nokogiri'
require 'open-uri'
fail("Usage: extract_links URL [URL ...]") if ARGV.empty?
ARGV.each do |url|
doc = Nokogiri::HTML(open(url))
hrefs = doc.css("a").map do |link|
if (href = link.attr("href")) && !href.empty?
URI::join(url, href)
end
end.compact.uniq
STDOUT.puts(hrefs.join("\n"))
end
Run Code Online (Sandbox Code Playgroud)
如果你只想要这个方法,可以根据你的需要重构一下:
def get_links(url)
Nokogiri::HTML(open(url).read).css("a").map do |link|
if (href = link.attr("href")) && href.match(/^https?:/)
href
end
end.compact
end
Run Code Online (Sandbox Code Playgroud)
Mechanize使用了Nokogiri,但内置了解析HTML的细节,包括链接:
require 'mechanize'
agent = Mechanize.new
page = agent.get('http://example.com/')
page.links_with(:href => /^https?/).each do |link|
puts link.href
end
Run Code Online (Sandbox Code Playgroud)
使用解析器通常总是比使用正则表达式解析HTML更好.这是Stack Overflow上经常被问到的问题,这是最着名的答案.为什么会这样?因为构建一个可以处理HTML的真实变体的健壮的正则表达式,其中一些不是有效的,非常困难,并且最终比简单的解析解决方案更复杂,该解决方案几乎适用于将在浏览器中呈现的所有页面.
我是Nokogiri的忠实粉丝,但为什么要重新发明轮子呢?
Ruby的URI模块已经有了extract这样做的方法:
URI::extract(str[, schemes][,&blk])
Run Code Online (Sandbox Code Playgroud)
来自文档:
从字符串中提取URI.如果给定块,则遍历所有匹配的URI.如果给定块或具有匹配的数组,则返回nil.
require "uri"
URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
# => ["http://foo.example.com/bla", "mailto:test@example.com"]
Run Code Online (Sandbox Code Playgroud)
您可以使用Nokogiri来遍历DOM并拉出所有包含URL的标记,或者让它只检索文本并将其传递给URI.extract,或者只是让URI.extract它们全部完成.
而且,为什么要使用像Nokogiri这样的解析器而不是正则表达式?因为HTML和XML可以通过许多不同的方式进行格式化,并且仍然可以在页面上正确呈现或有效地传输数据.在接受糟糕的标记时,浏览器非常宽容.另一方面,正则表达式模式在"可接受性"的非常有限的范围内工作,其中该范围由您预测标记变化的程度来定义,或者相反,您预测模式出错的方式有多好出现意想不到的模式.
解析器不像正则表达式那样工作.它构建了文档的内部表示,然后逐步完成.它并不关心文件/标记的布局方式,而是关注DOM的内部表示.Nokogiri放松了它的解析来处理HTML,因为HTML因写得不好而臭名昭着.这有助于我们,因为大多数非验证HTML Nokogiri可以解决它.偶尔我会遇到一些写得很糟糕的东西,Nokogiri无法正确修复它,所以我必须通过调整HTML来给它一点轻推,然后再把它传递给Nokogiri; 我仍然会使用解析器,而不是尝试使用模式.
| 归档时间: |
|
| 查看次数: |
8410 次 |
| 最近记录: |