2014-04-09 16 views
6

Ich versuche, Bilder von einigen URLs herunterzuladen. Für einige Bilder funktioniert es gut, für andere jedoch 403 Fehler.403 beim Versuch, ein Remote-Image herunterzuladen

Für exemple, dieses: http://blog.zenika.com/themes/Zenika/img/zenika.gif

Dieses Bild Zugang erfordert keine Authentifizierung. Sie können auf den Link klicken und prüfen, ob er für Ihren Browser mit einem 200-Statuscode verfügbar ist.

Der folgende Code erzeugt eine Ausnahme: new java.net.URL(url).openStream(). Dasselbe gilt für org.apache.commons.io.FileUtils.copyURLToFile(new java.net.URL(url), tmp) welches dasselbe openStream() Metho unter der Haube verwendet.

java.io.IOException: Server returned HTTP response code: 403 for URL: http://blog.zenika.com/themes/Zenika/img/zenika.gif 
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1626) ~[na:1.7.0_45] 
at java.net.URL.openStream(URL.java:1037) ~[na:1.7.0_45] 
at services.impl.DefaultStampleServiceComponent$RemoteImgUrlFilter$class.downloadAsTemporaryFile(DefaultStampleServiceComponent.scala:548) [classes/:na] 
at services.impl.DefaultStampleServiceComponent$RemoteImgUrlFilter$class.services$impl$DefaultStampleServiceComponent$RemoteImgUrlFilter$$handleImageUrl(DefaultStampleServiceComponent.scala:523) [classes/:na] 

ich mit Scala/Play-Framework entwickeln. Ich habe versucht, den integrierten AsyncHttpClient zu verwenden.

// TODO it could be better to use itetarees on the GET call becase I think AHC load the whole body in memory 
WS.url(url).get.flatMap { res => 
    if (res.status >= 200 && res.status < 300) { 
    val bodyStream = res.getAHCResponse.getResponseBodyAsStream 
    val futureFile = TryUtils.tryToFuture(createTemporaryFile(bodyStream)) 
    play.api.Logger.info(s"Successfully downloaded file $filename with status code ${res.status}") 
    futureFile 
    } else { 
    Future.failed(new RuntimeException(s"Download of file $filename returned status code ${res.status}")) 
    } 
} recover { 
    case NonFatal(e) => throw new RuntimeException(s"Could not downloadAsTemporaryFile url=$url", e) 
} 

Mit diesem AHC-Code funktioniert es gut. Kann jemand dieses Verhalten erklären und warum habe ich einen 403 Fehler mit der URL.openStream() Methode?

+1

Wie viel Anfragen Sie feuern ? Nur eine Vermutung - vielleicht werden Sie wegen der Überschreitung des Anforderungslimits gekickt? – serejja

+0

@serejja es ist nur eine einzige Anfrage, und ich habe dieses Problem auf verschiedenen Diensten Hosting von Bildern. Vielleicht können Sie versuchen, eine einzige 'neue java.net.URL (url) .openStream()' auf dieser URL und sehen Sie sich selbst dies ist kein Spam-Schutz –

+0

Einige Bild Hoster versuchen zu vermeiden, dass Bots Bilder herunterladen, also wenn sie erkennen, dass Anfrage nicht vom Browser gesendet wird, sie nur mit 403 Status, versuchen zu überprüfen, ob zB Pure Curl Anfrage von der Kommandozeile gibt Ihnen das richtige Bild – biesior

Antwort

3

Wie bereits erwähnt, verhindern einige Hoster dieses Eindringen einige Header wie Useragent mit:

val urls = """http://blog.zenika.com/themes/Zenika/img/zenika.gif""" 
    val url = new URL(urls) 
    val urlConnection = url.openConnection() 
    val inputStream = urlConnection.getInputStream() 
    val bufferedReader = new BufferedReader(new InputStreamReader(inputStream)) 

Dies funktioniert:

dies nicht funktioniert

val urls = """http://blog.zenika.com/themes/Zenika/img/zenika.gif""" 
val url = new URL(urls) 
val urlConnection = url.openConnection() 
urlConnection.setRequestProperty("User-Agent", """NING/1.0""") 
val inputStream = urlConnection.getInputStream() 
val bufferedReader = new BufferedReader(new InputStreamReader(inputStream)) 
Verwandte Themen