如果您使用 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://”。(您可能会遇到更多方案。有关更多信息,请参阅规范。)
在通用 URI 中,您可以使用一些规则对它们进行排序,以便在必须打开它们时知道如何做出反应。
如果您通过抓取页面收集 HREF 字符串,则可以假设如果相关 URI 不提供相同的方案和主机是安全的。因此,如果您最初加载了“http://www.someurl.com/index.html”,则可以使用“http://www.someurl.com/”作为进一步请求的基础。
从那里,查看字符串内部以确定它们是锚点、绝对路径还是相对路径。如果字符串:
- 从它开始
#
是一个锚点,将应用于当前页面而无需重新加载它。
- 不包含路径分隔符
/
,它是一个文件名,将添加到当前检索的 URL,替换文件名并检索。进行替换的一个好方法是使用File.dirname
,File.basename
并File.join
针对字符串。
- 以路径分隔符开头,它是绝对路径,用于替换原始 URL 中的路径。
URI::split
并且URI::join
是你这里的朋友。
- 不以路径分隔符开头,它是一个相对路径,并类似于#2 添加到当前 URI。
关于:
hrefvalue = []
html.css('a').each do |atag|
hrefvalue << atag['href']
end
我会改用这个:
hrefvalue = html.search('a').map { |a| a['href'] }
但这只是我。
最后一点:URI 存在一些年龄问题,需要更新。这是一个有用的库,但对于重型 URI 撕裂,我强烈建议考虑使用Addressable/URI。