从URL 1)下载Java文件,您不需要';我不知道扩展名[e.jpg]或2)正在重定向到文件

从URL 1)下载Java文件,您不需要';我不知道扩展名[e.jpg]或2)正在重定向到文件,java,file,download,urlconnection,Java,File,Download,Urlconnection,问题是,尽管我知道如何从URL下载文件,例如: 当涉及以下文件时: 我不知道如何下载它 如果扩展名可见,我用来下载文件的代码非常有效,但在上述示例中返回: java.io.IOException: Server returned HTTP response code: 500 for URL: https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fimages2.fanpop.com%2Fimage%2Fphotos%2F8900000%2FF

问题是,尽管我知道如何从
URL
下载
文件,例如:


当涉及以下文件时:

我不知道如何下载它


如果扩展名可见,我用来下载文件的代码非常有效,但在上述示例中返回:

java.io.IOException: Server returned HTTP response code: 500 for URL: https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fimages2.fanpop.com%2Fimage%2Fphotos%2F8900000%2FFirefox-firefox-8967915-1600-1200.jpg&f=1
即使您删除了
&f=1


下载程序的代码(用于测试…原型):

下载ProgressListener的代码:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.io.output.CountingOutputStream;

public class DownloadProgressListener extends CountingOutputStream {

    private ActionListener listener = null;

    public DownloadProgressListener(OutputStream out) {
    super(out);
    }

    public void setListener(ActionListener listener) {
    this.listener = listener;
    }

    @Override
    protected void afterWrite(int n) throws IOException {
    super.afterWrite(n);
    if (listener != null) {
        listener.actionPerformed(new ActionEvent(this, 0, null));
    }
    }

}
我在发帖前读到的问题:

(一)

(二)

(三)

(四)


5)

正如评论中指出的,扩展是不相关的

这里的问题是试图下载可能是re-direct或可能只是异步调用参数的内容

没有扩展名的超大url已损坏,但我可以回答另一种类型的潜在解决方案

如果您观察URL:

https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fimages2.fan‌​pop.com%2Fimage%2Fph‌​otos%2F8900000%2FIR‌​efox-firefox-8967915‌​-1600-1200。jpg&f=1

图像的URL实际上就在那里。它只是编码的,应该很容易解码。Java(Java.net.urldecker)中包含了解码库,但如果您希望自己进行解码,可以这样看:

http%3A%2F%2Fimages2.fan‌​pop.com%2Fimage%2Fph‌​otos%2F8900000%2FIR‌​efox-firefox-8967915‌​-1600-1200。jpg&f=1

编码部分是
%XX
,其中
XX
是任意两个字符。查看HTML编码表,您将看到
%3A
显然是冒号<代码>%2F
是正斜杠

如果替换所有编码的实体,最终将得到:
http://images2.fan‌​pop.com/image/ph‌​otos/8900000/Fir‌​efox-firefox-8967915‌​-1600-1200。jpg&f=1

在这种情况下,您不需要额外的参数,因此可以放弃
&f=1
并从原始URL下载图像。在大多数情况下,我想您可以保留额外的参数,而忽略它

--

简言之:

  • 提取原始URL
  • 破译
  • 下载
  • 我想指出的是,这是一个脆弱的解决方案,如果URL模式发生变化,它将崩溃,或者需要大量维护。如果你的目标不仅仅是一小部分用户,你应该重新考虑你的方法

    如果你想要一种“快速而肮脏”的方法来解决问题,请看@Christopher Schneider的答案。(但如果DuckDuckGo的URL语法发生变化,它可能会崩溃…)

    我做了一些深入研究(使用
    curl--traceascii
    等)。这不是重定向的问题。根据
    curl
    ,500是对请求的即时响应

    所以我最好的猜测是这种行为是“故意的”。服务器正在查看请求头(例如“用户代理”头),并确定您的请求看起来不像来自受支持的浏览器。500响应是故意或意外的混淆

    为什么?

    最有可能的是,运行DuckDuckGo的人不希望您使用该服务器端点进行自动下载、抓取等操作。他们并不完全清楚这一点,但这个链接在某种程度上解释了:

    解决方案


    别这样!看看你是否可以使用他们的官方API(见上文)来做你想做的事情。如果这不起作用,联系他们

    这与分机无关。@shmosel如果我错了,你可以更正标题。我就是这样想的。它与重定向有关?正如shmosel指出的,扩展并不重要。问题是试图下载可能是重定向或其他查询的内容。我不确定是否有任何简单的解决方案,但如果您看看:
    https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fimages2.fanpop.com%2Fimage%2Fphotos%2F8900000%2FFirefox-firefox-8967915-1600-1200.jpg&f=1
    ,实际上有一个指向图像的URL,您可以对其进行解析。谢谢Christopher,现在我明白了,在阅读了你提供的链接并成功下载了图片之后。我正在遵循您在1、2、3结尾提供的步骤。困难的部分是1如何提取原始URL。。。。?例如,这里有
    http://images2.fan‌​pop.com/image/ph‌​otos/8900000/Fir‌​efox-firefox-8967915‌​-1600-1200.jpg&f=1
    在剪切解码url的一部分后…(
    https://images.duckduckgo.com/iu/?u=
    )]2和3做得很容易。我不确定我能不能帮你回答这个问题。你想从多个地方下载吗?就这么走了吗?您需要了解如何根据源提取URL。查看URL,如果他们总是在每个图像URL前面加上
    https://images.duckduckgo.com/iu/?u=
    您只需从字符串的开头剪掉它,就完成了。您还可以查找http%3A%2F%2F,并将其用作URL的开头。这里可以用正则表达式。查看
    java.util.regex.Matcher
    。特别是
    find()
    start()
    重新阅读您的评论,我想我没有提到它。正如我在对你的问题的最初评论中所说,没有简单的解决方案,我不确定你实际上是如何实现这一点的。如果您只有URL,则需要创建某种能够解析URL并尝试查找嵌入这些URL中的URL的算法。是的,检测http%3A%2F%2F是一种可能的解决方案。但它对其他网络搜索者(如谷歌)也会起作用。。?我希望用户能够使用我的应用程序下载文件。同样使用代码found()我看到
    ht
    
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import java.io.OutputStream;
    
    import org.apache.commons.io.output.CountingOutputStream;
    
    public class DownloadProgressListener extends CountingOutputStream {
    
        private ActionListener listener = null;
    
        public DownloadProgressListener(OutputStream out) {
        super(out);
        }
    
        public void setListener(ActionListener listener) {
        this.listener = listener;
        }
    
        @Override
        protected void afterWrite(int n) throws IOException {
        super.afterWrite(n);
        if (listener != null) {
            listener.actionPerformed(new ActionEvent(this, 0, null));
        }
        }
    
    }