如何在href中识别路径/文件/ url

时间:2012-10-22 19:28:29

标签: html ruby html-parsing nokogiri

我正在尝试使用Nokogiri获取href HTML标记中的<a>值。

我想确定它们是路径,文件,网址,还是<div> ID。

我目前的工作是:

hrefvalue = []
html.css('a').each do |atag|
        hrefvalue << atag['href']
end

href中的可能值可能是:

somefile.html
http://www.someurl.com/somepath/somepath
/some/path/here
#previous

是否有机制来确定该值是有效的完整URL,文件,路径还是其他?

3 个答案:

答案 0 :(得分:3)

尝试URI:

require 'uri'

URI.parse('somefile.html').path
=> "somefile.html"

URI.parse('http://www.someurl.com/somepath/somepath').path
=> "/somepath/somepath"

URI.parse('/some/path/here').path
=> "/some/path/here"

URI.parse('#previous').path
=> ""

答案 1 :(得分:2)

Nokogiri经常与ruby的URI或open-uri一起使用,所以如果你的情况就是如此,你就可以访问它的方法了。您可以使用它来尝试解析URI(使用URI.parse)。如果您存储了base_uri,通常也可以使用URI.join(base_uri, retrieved_href)构建完整的URL。

(编辑/侧注:有关使用URI.join的更多详细信息,请访问:https://stackoverflow.com/a/4864170/624590;请注意URI.join将字符串作为参数,而非URI对象,因此强制执行必要)

基本上,回答你的问题

  

是否有机制来确定该值是否为有效的完整值   网址,文件,路径或其他?

如果retrieve_href和base_uri格式正确,并且retrieve_href ==连接对,则它是绝对路径。否则它是相对的(再次,假设输入良好)。

答案 2 :(得分:1)

如果使用URI来解析href值,那么对结果应用一些启发式算法,就可以弄清楚你想知道什么。这基本上是浏览器在发送页面或资源请求时必须执行的操作。

使用您的示例字符串:

%w[
  somefile.html
  http://www.someurl.com/somepath/somepath
  /some/path/here
  #previous
].each do |u|
  puts URI.parse(u).class
end

结果:

URI::Generic
URI::HTTP
URI::Generic
URI::Generic

URI识别为真正的HTTP URI的唯一一个是“http://www.someurl.com/somepath/somepath”。所有其他人都错过了“http://”计划。 (您可以遇到更多方案。有关详细信息,请参阅specification。)

在通用URI中,您可以使用一些规则对它们进行排序,以便在必须打开它们时知道如何做出反应。

如果您通过抓取页面来收集HREF字符串,则可以假设使用相同的方案和主机是安全的,如果有问题的URI没有提供。因此,如果您最初加载“http://www.someurl.com/index.html”,则可以使用“http://www.someurl.com/”作为进一步请求的基础。

从那里,查看字符串内部以确定它们是锚点,绝对路径还是相对路径。如果是字符串:

  1. #开始,它是一个锚点,无需重新加载即可应用于当前页面。
  2. 不包含路径分隔符/,它是一个文件名,将被添加到当前检索的URL中,替换文件名并进行检索。一种很好的替换方法是对字符串使用File.dirnameFile.basenameFile.join
  3. 以路径分隔符开头,它是绝对路径,用于替换原始URL中的路径。 URI::splitURI::join是您的朋友。
  4. 不以路径分隔符开头,它是相对路径,与#2类似地添加到当前URI。
  5. 关于:

    hrefvalue = []
    html.css('a').each do |atag|
            hrefvalue << atag['href']
    end
    

    我会改用它:

    hrefvalue = html.search('a').map { |a| a['href'] }
    

    但那只是我。

    最后一点:URI存在一些年龄问题,需要更新。它是一个有用的库,但是,对于重载URI rippin',我强烈建议使用Addressable/URI