2016-11-07 2 views
1

Socketを使用して、httpリクエストをサーバに送信し、html応答を取得できます。私の目的は、各画像をpng, jpeg, gif,または他の画像タイプにすることです。HTTPレスポンスのJavaフィルタ画像

しかし、さまざまなウェブサイトからの回答を見ると、HTMLの<img>タグを使用していない画像があり、代わりにCSSに表示されることがあります。 <img>画像とcss画像(たとえばbackground-image)の両方を抽出するにはどうすればよいですか? 正規表現を使って画像URLを<img>から得るのは良いですか?

Apache HttpClientのようなhttpクラスには参照しないでください。 私の問題はhttpプロトコルではありません。

+2

あなたの質問を明確にするための基本的なコードを提供してください –

答えて

1

その他の回答は既に述べたとおり、HTTPリソース(つまり、.html/css/js/png/gif/jpg/etc)の解析、レンダリング、再帰を理解するツールを使用するのが理想的です。あなたが特に自虐感じていた(と私はあなたがしている疑いがある)場合は、言われていること

、あなたはこれを自分で行うことができます...

これは完璧な解決策ではないですが、私はこれを攻撃するつもりだった場合私は正規表現を使用したいと思います(私は正規表現の詳細には入りません、それはすでにwidely documented on the interwebsです)。私のプロセスは次のようになります:

  1. HTTPは私のベースページを取得します。
  2. "リソース"の定義(正規表現を使用)に一致するすべての文字列を取り除きます。
  3. 必要に応じて、これらのリソースを再帰的に処理し、より多くの文字列を取得します。

すでにHTTPリクエスト/レスポンス(ソケットを使用)を実行できると述べたので、ここでは説明しません。

Voila!

/** 
* Regular expression to match file types - .js/.css/.png/.jpg/.gif 
*/ 
public static final Pattern resources = Pattern.compile("([^\"'\n({}]+\\.(js|css|png|jpg|gif))", 
     Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); 

/** 
* Pulls out "resources" from the provided text. 
*/ 
public static Set<String> findResources(URL url, String text) { 
    Matcher matcher = resources.matcher(text); 
    Set<String> resources = new HashSet<>(); 
    while (matcher.find()) { 
     String resource = matcher.group(1); 
     String urlStr = url.toString(); 
     int endIndex = urlStr.lastIndexOf("/") + 1; 
     String parentPath = endIndex > 0 ? urlStr.substring(0, endIndex) : urlStr; 
     String fqResource = resource.startsWith("//") ? url.getProtocol() + ":" + resource : 
       resource.startsWith("http") ? resource 
         : resource.startsWith("/") ? getBaseUrl(url) + resource : parentPath + resource; 
     if (fqResource.contains("?")) { 
      fqResource = fqResource.substring(0, fqResource.indexOf("?")); 
     } 
     resources.add(fqResource); 
    } 
    return resources; 
} 

正規表現:css/js/png/gif/jpg

方法を終わる整形文字列を探します:は、指定されたテキスト(別名「HTTPレスポンス」)から一致するすべての文字列を取得し、構築しようとします完全修飾URLを返し、データのSetを返します。

full example here(サンプル出力あり)をアップロードしました。楽しむ!

-2

JSoup HTML & XMLパーサを使用できます。ここ は

String responseData = ""; // HTML data 
Document doc = Jsoup.parse(responseData); 
Elements images = doc.select("img"); 
// Elements pngImages = doc.select("img[src$=.png]"); 
// To parse specific image format in this case png 
for(Element image : images){ 
    // Do what ever you wanted to do 
} 

Here is related official documentation、それを行う方法の例です。

+1

これはCSSによって使用/読み込まれた画像を抽出しません。私は正規表現ではなくJSoupを使うだろう。それはもっと信頼できる。 –

4

cssやおそらくjsによって読み込まれた画像を含むすべての画像を取得するには、htmlコード以上のものが必要です。 htmlとcssとjsを理解するコードが必要です。 フルブラウザが必要です。

幸い、Javaにはブラウザが付属しています。 JavaFXWebEngine。 URLまたはHTMLを指定すると、すべてがロードされます。 WebKitとして、最新の画像読み込み技術、例えばCSS border-imageを知っています。

画像を取得する方法が必要です。 それはmedia listを提供していませんが、それは純粋なJavaのであるから、私たちはその要求をインターセプトするためにJavaのURLハンドラをハイジャックすることができます

import java.io.IOException; import java.net.URL; import java.net.URLConnection; import javafx.application.Application; import javafx.application.Platform; import javafx.concurrent.Worker; import javafx.scene.Scene; import javafx.scene.web.WebView; import javafx.stage.Stage; 

public class NetworkMonitor extends Application { 

    private final String url = "http://www.google.com/"; 

    public static void main(String[] args) { 
     // Override default http/https handler. Must do once only. 
     URL.setURLStreamHandlerFactory(protocol -> 
     protocol.equals("http") ? new HttpHandler() : 
     protocol.equals("https") ? new HttpsHandler() : null); 
     // Launch as JavaFX app. Required for WebView/WebEngine. 
     launch(args); 
    } 

    @Override public void start(Stage primaryStage) throws Exception { 
     // Create webview and listen for ondone 
     WebView v = new WebView(); 
     v.getEngine().getLoadWorker().stateProperty().addListener((prop, old, now) -> { 
     if (now == Worker.State.SUCCEEDED || now == Worker.State.FAILED) 
      Platform.exit(); }); 
     // Showing GUI is easiest way to make sure ondone will be fired. 
     primaryStage.setScene(new Scene(v)); 
     primaryStage.show(); 
     // Load the target url. 
     v.getEngine().load(url); 
    } 

    // Your IDE should warn you about the sun package. 
    private static class HttpHandler extends sun.net.www.protocol.http.Handler { 
     @Override protected URLConnection openConnection(URL url) throws IOException { 
     System.out.println(url); // Capture url! 
     return super.openConnection(url); 
     } 
    } 

    // If there is no warning, you need to switch to a better IDE! 
    private static class HttpsHandler extends sun.net.www.protocol.https.Handler { 
     @Override protected URLConnection openConnection(URL url) throws IOException { 
     System.out.println(url); // Capture url! 
     return super.openConnection(url); 
     } 
    } 
} 

あなただけのURLを取得する方法を求めているので、これはコードが何をすべきかです。 必要に応じてコードを拡張することができます。

たとえば、2つのdecoratorのURLConnectionオブジェクトを使用すると、getInputStreamの呼び出しを傍受し、ヘッダー(MIMEタイプを判別)とストリームをフォーク(画像のコピーを保存)することができます。

この回答が役に立つ場合は、投票することを忘れないでください!

関連する問題