2017-01-28 11 views
2

FileURLからダウンロードする方法はわかっていますが、問題があります。例:URLからファイルをダウンロードする1)拡張子[例:.jpg]または2)がファイルにリダイレクトする

http://i12.photobucket.com/albums/a206/zxc6/1_zps3e6rjofn.jpg


それは以下のようなファイルに来る:

https://images.duckduckgo.com/iu/?u=http%3......

Iヘクタールそれをダウンロードする手がかりはありません。


私はIOUtilsでファイルをダウンロードするために使用していたコードの拡張子が表示されているが、上記の例の場合に返された場合、それは素晴らしい作品:

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を削除しても。


Downloaderのコード(それは....テスト目的のためのプロトタイプです):私は投稿する前に読んだことがある

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)); 
    } 
    } 

} 

質問:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.URL; 
import java.net.URLConnection; 

import org.apache.commons.io.IOUtils; 

public class Downloader { 

    private static class ProgressListener implements ActionListener { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     // e.getSource() gives you the object of 
     // DownloadCountingOutputStream 
     // because you set it in the overriden method, afterWrite(). 
     System.out.println("Downloaded bytes : " + ((DownloadProgressListener) e.getSource()).getByteCount()); 
    } 
    } 

    /** 
    * Main Method 
    * 
    * @param args 
    */ 
    public static void main(String[] args) { 
    URL dl = null; 
    File fl = null; 
    String x = null; 
    OutputStream os = null; 
    InputStream is = null; 
    ProgressListener progressListener = new ProgressListener(); 
    try { 
     fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/image.jpg"); 
     dl = new URL(
      "https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fimages2.fanpop.com%2Fimage%2Fphotos%2F8900000%2FFirefox-firefox-8967915-1600-1200.jpg&f=1"); 
     os = new FileOutputStream(fl); 
     is = dl.openStream(); 

     // http://i12.photobucket.com/albums/a206/zxc6/1_zps3e6rjofn.jpg 

     DownloadProgressListener dcount = new DownloadProgressListener(os); 
     dcount.setListener(progressListener); 

     URLConnection connection = dl.openConnection(); 

     // this line give you the total length of source stream as a String. 
     // you may want to convert to integer and store this value to 
     // calculate percentage of the progression. 
     System.out.println("Content Length:" + connection.getHeaderField("Content-Length")); 
     System.out.println("Content Length with different way:" + connection.getContentType()); 

     System.out.println("\n"); 

     // begin transfer by writing to dcount, not os. 
     IOUtils.copy(is, dcount); 

    } catch (Exception e) { 
     System.out.println(e); 
    } finally { 
     IOUtils.closeQuietly(os); 
     IOUtils.closeQuietly(is); 
    } 
    } 
} 

コードDownloadProgressListener用:

1)Download file from url that doesn't end with .extension

2)http://www.mkyong.com/java/how-to-get-url-content-in-java/

3)Download file using java apache commons?

4)How to download and save a file from Internet using Java?

5)How to create file object from URL object

+0

これは拡張機能とは関係ありません。 – shmosel

+0

@shmosel私は間違っている場合は、タイトルを修正することができます。それは私がそれをどのようにしているのかです。それはリダイレクトと関係がありますか? – GOXR3PLUS

+0

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を解析することができます。 –

答えて

3

コメントで指摘したように、拡張は無関係です。

ここで問題となっているのは、おそらくリダイレ​​クトや非同期呼び出しのパラメータをダウンロードしようとすることです。

拡張子のない非常に大きなURLは壊れていますが、私は他のタイプの潜在的な解決策に答えることができます。

URLを観察する場合:画像のURLが実際にある

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

。それはちょうどエンコードされ、デコードするのはかなり簡単なはずです。 Javaにはデコードライブラリが含まれています(java.net。URLDecoderのは)、しかし、あなたはそれをこのように見ることができ、それを自分で行うことを希望する必要があります。

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

エンコードされた部分がXXは、任意の2つの文字です%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。ほとんどの場合、私はあなたが余分なパラメータを保持することができ、それは無視されると思います。

  1. 元のURLを抽出し、それを私は、これは壊れやすいと指摘したいと思います
  2. ダウンロード

をデコード:一言で言えば

-

URLパターンが変更されたり、多くのメンテナンスが必要になったりした場合に破損する可能性があります。少人数のユーザーをターゲットにする場合は、アプローチを再考する必要があります。

HTML URL encoding table

+0

Christopherありがとう、私はあなたが提供したリンクを読んでそれを理解し、イメージを正常にダウンロードしました。私はあなたが最後に1,2,3で提供した手順に従っています。難しい部分は、どのように元の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はやりやすいです。 – GOXR3PLUS

+0

私はあなたのためにそれに答えることができるか分からない。複数の場所からダウンロードしたいですか?それはちょうどduckduckgoですか?ソースに応じてURLを抽出する方法を理解する必要があります。 URLを見ると、すべての画像のURLに 'https://images.duckduckgo.com/iu/?u = 'という文字列が付いていれば、文字列の先頭から切り取るだけで済みます。また、 'http%3A%2F%2F'を探して、URLの先頭として使用することもできます。正規表現はここで大丈夫でしょう。 'java.util.regex.Matcher'を見てください。特に 'find()'と 'start()' –

+0

あなたのコメントを読んで、私はそれに対処したとは思わない。あなたの質問に対する私の元のコメントで言ったように、単純な解決策はありません。実際にこれをどのように実装しているのか分かりません。あなたが持っているものがすべてURLの場合は、URLを解析してそれらのURLに埋め込まれたURLを見つけようとする何らかのアルゴリズムを作成する必要があります。 –

3

あなたが問題を解決するために「間に合わせ」方法をしたい場合は、@Christopherシュナイダーの答えを見てください。 (ただし、DuckDuckGoのURL構文が変更された場合は破損する可能性があります...)

私は少し掘り下げました(curl --trace-asciiなどを使用しています)。これはリダイレクトの問題ではありません。 curlによれば、500は要求に対する即時応答です。

だから私の最高の推測は、この動作が「設計通り」であるということです。サーバーはリクエストヘッダー(「User-Agent」ヘッダーなど)を見て、リクエストがサポートされているブラウザからのものかどうかを判断しています。 500応答は、故意または偶発的な難読化です。

なぜですか?

ほとんどの場合、DuckDuckGoを実行している人は、自動的にダウンロード、スクレイピングなどを行うためにそのサーバーエンドポイントを使用することは望ましくありません。彼らはそれについて完全には明らかではありませんが、このリンクは説明するためにいくつかの道を行く:

ソリューション?

しないでください!公式のAPIを使ってやろうとしていることを実行できるかどうかを確認してください(上記参照)。それでも問題が解決しない場合は、に連絡してください。

+0

私のアプリケーションを使って一般的にファイルをダウンロードできるようにします。だから問題は複雑に思えますが、Christoperのおかげで私は回避策を見つけることができました:)。また、見つかったコード(http://www.mkyong.com/java/java-httpurlconnection-follow-redirect-example/)を使って、 'html.toString()'が '.jpg'画像のコードを返していることがわかりますだから私はFileWriterを使って試して、 'File'にエクスポートして' .jpg'として保存しました。 Painterで開こうとすると、うまくいきません.... Strange .. – GOXR3PLUS

+0

+1。私はこの答えに同意します。私の答えは間違いなく「素早く汚れました」でしたが、提供された情報(URL文字列)に基づいて回答していました。私はこのようなことをするために多くのスクリプトを書いてきましたが、私はそれらを私とおそらく壊れやすく、ある時点で壊れるであろうアスタリスクを持ついくつかの他の開発者に書きます。 @ GOXR3PLUSが正当な消費者向きのソフトウェアを書くために探しているなら、彼らは自分の考えを破棄し、この答えに従うべきです。 –

関連する問題