传递具有片段标识符的URL时OpenURI存在问题

时间:2016-06-15 20:24:47

标签: ruby open-uri fragment-identifier

我需要从文本文件中读取一系列URL,然后检索页面并输出链接列表。

只要输入的网址包含片段标识符(#),代码就会出现问题。我尝试用%23来逃避这些,但这似乎没有帮助。

给出的错误来自OpenURI,是404。

#requirements
require 'nokogiri'
require 'open-uri'
#opening each line in input text file
line_num=0
text=File.open('input.txt').read
text.gsub!(/\r\n?/, "\n")
text.each_line do |line|
    print "#{line_num += 1} #{line}"
    open('output.txt', 'a') { |f|
        f.puts "#{line_num} #{line}"
    }
    uri = URI.parse(URI.encode(line.strip))
    page = Nokogiri::HTML(open(uri))   
    links = page.css("div.product-carousel-container a")
    #loop through links if present
    e = 0
    while e < links.length
        open('output.txt', 'a') { |f|
        f.puts links[e]["href"]
        }
        e += 1
    end  
end

2 个答案:

答案 0 :(得分:0)

问题

不应将URI的片段部分发送到服务器。

来自Wikipedia: Fragment Identifier

  

片段标识符的功能与URI的其余部分不同:即,它的处理完全是客户端的,没有Web服务器的参与 - 当然,服务器通常有助于确定MIME类型,MIME类型确定处理碎片。当代理(例如Web浏览器)从Web服务器请求Web资源时,代理会将URI发送到服务器,但不会发送该片段。相反,代理等待服务器发送资源,然后代理根据文档类型和片段值处理资源。

解决方案

在将URI传递给open之前删除URI的片段部分。

require "uri"

u = URI.parse "http://example.com#fragment"
u.fragment = nil
u.to_s #=> "http://example.com"

答案 1 :(得分:0)

你90%的方式都在那里。客户端负责处理片段。

您的代码已经使用URI来解析字符串,因此请让解析后的对象删除片段:

require 'open-uri'
uri = URI.parse('http://foo.com/index.html#bar')
uri # => #<URI::HTTP http://foo.com/index.html#bar>
uri.fragment = nil
uri # => #<URI::HTTP http://foo.com/index.html>