【问题标题】:Only OpenURI succeeds at Reddit API requestReddit API 请求中只有 OpenURI 成功
【发布时间】:2021-05-20 23:28:46
【问题描述】:

我正在向 Reddit API 发出请求。首先,我设置了一个 subreddit 顶部 URL:

reddit_url = URI.parse('https://www.reddit.com/r/pixelart/top.json')

所有这些都正确获取内容:

Net::HTTP.get(reddit_url, 'User-Agent' => 'My agent')

Open3.capture2('/usr/bin/curl', '--user-agent', 'My agent', reddit_url.to_s)[0]

URI.open(reddit_url, 'User-Agent' => 'My agent').read

然后我尝试使用特定帖子的 URL:

reddit_url = URI.parse('https://reddit.com/r/PixelArt/comments/lkaiqf/another_watercolour_pixelart_tree.json')

Net::HTTPOpen3/curl 都失败了,只得到空字符串。 URI.open 继续有效,在网络浏览器中打开 URL 也是如此。

为什么第二个请求不适用于两个解决方案?为什么它可以与URI.open 一起使用,而它应该是“an easy-to-use wrapper for Net::HTTP”?它有什么不同,以及如何使用Net::HTTPcurl 复制它?

【问题讨论】:

    标签: ruby curl net-http open-uri


    【解决方案1】:

    使用您的示例,并为简单起见专注于 Net::HTTP,第一个示例无法按所写的那样工作:

    require 'net/http'
    reddit_url = URI.parse('https://www.reddit.com/r/pixelart/top.json')
    Net::HTTP.get(reddit_url, 'User-Agent' => 'My agent')
    # => Type Error - no implicit conversion of URI::HTTPS into String
    

    相反,我以此为出发点:

    require 'net/http'
    reddit_url = URI.parse('https://www.reddit.com/r/pixelart/top.json')
    http = Net::HTTP.new(reddit_url.host, reddit_url.port)
    http.use_ssl = true
    result = http.get(reddit_url.request_uri, 'User-Agent' => 'My agent')
    puts result
    # => #<Net::HTTPOK:0x00007fc3ea8e7320>
    puts result.body.size
    # => 167,394
    

    通过这个工作,我们可以尝试第二个 URL。有趣的是,根据我是重复使用初始连接还是建立新连接,我会得到不同的结果:

    require 'net/http'
    reddit_url = URI.parse('https://www.reddit.com/r/pixelart/top.json')
    reddit_url_two = URI.parse('https://reddit.com/r/PixelArt/comments/lkaiqf/another_watercolour_pixelart_tree.json')
    
    http = Net::HTTP.new(reddit_url.host, reddit_url.port)
    http.use_ssl = true
    result = http.get(reddit_url.request_uri, 'User-Agent' => 'My agent')
    puts result
    # => #<Net::HTTPOK:0x00007f931a143390>
    puts result.body.size
    # => 174,615
    
    http_two = Net::HTTP.new(reddit_url_two.host, reddit_url_two.port)
    http_two.use_ssl = true
    result_two = http_two.get(reddit_url_two.request_uri, 'User-Agent' => 'My agent')
    puts result_two
    # => #<Net::HTTPMovedPermanently:0x00007f931a148818>
    puts result_two.body.size
    # => 0
    
    result_reusing_connection = http.get(reddit_url_two.request_uri, 'User-Agent' => 'My agent')
    puts result_reusing_connection
    # => #<Net::HTTPOK:0x00007f931a0fb3b0>
    puts result_reusing_connection.body.size
    # => 141,575
    

    所以我怀疑您有时会收到 301 重定向,这会造成混乱。还有另一个 question and answer here 用于了解如何跟踪重定向。

    【讨论】:

    • 第一个示例适用于 Ruby 3.0,但似乎不适用于旧版本。这或许可以解释这一点的差异。你说得对,重定向是问题所在(真不敢相信我忘了尝试 curl--location),但奇怪的是它似乎指向同一个 URL。
    • 你说得对,显然我还在使用 2.7.2。我仍然不确定为什么重用第一个连接有效...从浏览器访问时我看不到重定向...那里有一些令人费解的事情,但很高兴您现在走上了正轨!
    猜你喜欢
    • 2018-06-05
    • 2020-04-12
    • 2021-11-27
    • 2013-06-19
    • 2021-11-24
    • 2019-03-11
    • 1970-01-01
    • 2016-11-20
    • 2016-06-04
    相关资源
    最近更新 更多