¿Cómo leer el contenido html desde esta página con Java?

Mi aplicación Java intenta leer contenido de la siguiente url: https://www.iplocation.net/?query=62.92.63.48

Usé el siguiente método:

StringBuffer readFromUrl(String Url) { StringBuffer sb=new StringBuffer(); BufferedReader in=null; try { in=new BufferedReader(new InputStreamReader(new URL(Url).openStream())); String inputLine; while ((inputLine=in.readLine()) != null) sb.append(inputLine+"\n"); in.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (in!=null) { in.close(); in=null; } } catch (Exception ex) { ex.printStackTrace(); } } return sb; } 

Por lo general, funciona bien para otras URL, pero para esta, el resultado es diferente de lo que se muestra en un navegador, se ve así:

     (function(){function getSessionCookies(){var cookieArray=new Array();var cName=/^\s?incap_ses_/;var c=document.cookie.split(";");for(var i=0;i<c.length;i++){var key=c[i].substr(0,c[i].indexOf("="));var value=c[i].substr(c[i].indexOf("=")+1,c[i].length);if(cName.test(key)){cookieArray[cookieArray.length]=value}}return cookieArray}function setIncapCookie(vArray){var res;try{var cookies=getSessionCookies();var digests=new Array(cookies.length);for(var i=0;i<cookies.length;i++){digests[i]=simpleDigest((vArray)+cookies[i])}res=vArray+",digest="+(digests.join())}catch(e){res=vArray+",digest="+(encodeURIComponent(e.toString()))}createCookie("___utmvc",res,20)}function simpleDigest(mystr){var res=0;for(var i=0;i<mystr.length;i++){res+=mystr.charCodeAt(i)}return res}function createCookie(name,value,seconds){var expires="";if(seconds){var date=new Date();date.setTime(date.getTime()+(seconds*1000));var expires="; expires="+date.toGMTString()}document.cookie=name+"="+value+expires+"; path=/"}function test(o){var res="";var vArray=new Array();for(var j=0;j<o.length;j++){var test=o[j][0];switch(o[j][1]){case"exists":try{if(typeof(eval(test))!="undefined"){vArray[vArray.length]=encodeURIComponent(test+"=true")}else{vArray[vArray.length]=encodeURIComponent(test+"=false")}}catch(e){vArray[vArray.length]=encodeURIComponent(test+"=false")}break;case"value":try{try{res=eval(test);if(typeof(res)==="undefined"){vArray[vArray.length]=encodeURIComponent(test+"=undefined")}else if(res===null){vArray[vArray.length]=encodeURIComponent(test+"=null")}else{vArray[vArray.length]=encodeURIComponent(test+"="+res.toString())}}catch(e){vArray[vArray.length]=encodeURIComponent(test+"=cannot evaluate");break}break}catch(e){vArray[vArray.length]=encodeURIComponent(test+"="+e)}case"plugin_extentions":try{var extentions=[];try{i=extentions.indexOf("i")}catch(e){vArray[vArray.length]=encodeURIComponent("plugin_ext=indexOf is not a function");break}try{var num=navigator.plugins.length if(num==0||num==null){vArray[vArray.length]=encodeURIComponent("plugin_ext=no plugins");break}}catch(e){vArray[vArray.length]=encodeURIComponent("plugin_ext=cannot evaluate");break}for(var i=0;i1){ext=filename.split('.').pop()}if(extentions.indexOf(ext)<0){extentions.push(ext)}}for(i=0;i<extentions.length;i++){vArray[vArray.length]=encodeURIComponent("plugin_ext="+extentions[i])}}catch(e){vArray[vArray.length]=encodeURIComponent("plugin_ext="+e)}break}}vArray=vArray.join();return vArray}var o=[["navigator","exists"],["navigator.vendor","value"],["navigator.appName","value"],["navigator.plugins.length==0","value"],["navigator.platform","value"],["navigator.webdriver","value"],["platform","plugin_extentions"],["ActiveXObject","exists"],["webkitURL","exists"],["_phantom","exists"],["callPhantom","exists"],["chrome","exists"],["yandex","exists"],["opera","exists"],["opr","exists"],["safari","exists"],["awesomium","exists"],["puffinDevice","exists"],["navigator.cpuClass","exists"],["navigator.oscpu","exists"],["navigator.connection","exists"],["window.outerWidth==0","value"],["window.outerHeight==0","value"],["window.WebGLRenderingContext","exists"],["document.documentMode","value"],["eval.toString().length","value"]];try{setIncapCookie(test(o));document.createElement("img").src="/_Incapsula_Resource?SWKMTFSR=1&e="+Math.random()}catch(e){img=document.createElement("img");img.src="/_Incapsula_Resource?SWKMTFSR=1&e="+e}})();   (function() { var z="";var b="7472797B766172207868723B76617220743D6E6577204461746528292E67657454696D6528293B766172207374617475733D2273746128......6F6465555249436F6D706F6E656E74287374617475732B222028222B74696D696E672E6A6F696E28292B222922297D3B";for (var i=0;i<b.length;i+=2){z=z+parseInt(b.substring(i, i+2), 16)+",";}z = z.substring(0,z.length-1); eval(eval('String.fromCharCode('+z+')'));})();     

Entonces, ¿cuál es la forma correcta de leer el contenido html que aparece en el navegador, en este caso?

Editar: Después de leer las sugerencias, actualicé mi progtwig para que se vea como el siguiente:

 StringBuilder response=new StringBuilder(); String USER_AGENT="Mozilla/5.0",inputLine; BufferedReader in=null; try { HttpURLConnection con=(HttpURLConnection)new URL(Url).openConnection(); con.setRequestMethod("GET"); con.setRequestProperty("Accept-Charset","UTF-8"); con.setRequestProperty("User-Agent",USER_AGENT); // Add request header int responseCode=con.getResponseCode(); in=new BufferedReader(new InputStreamReader(con.getInputStream())); while ((inputLine=in.readLine())!=null) { response.append(inputLine); } in.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (in!=null) in.close(); } catch (Exception ex) { ex.printStackTrace(); } } return response.toString(); 

Sin embargo, todavía no funcionó, la respuesta que obtuve es la siguiente:

 Request unsuccessful. Incapsula incident ID: 516000100118713619-514529209419563176 

¿Podría alguien mostrar algún código de muestra que funcione?

Gracias a @thatguy modifiqué mi progtwig para que se pareciera a lo siguiente:

 import java.util.*; import java.util.concurrent.*; import java.io.*; import java.net.*; import java.util.Map.Entry; public class Read_From_Url_Runner implements Callable { int Id; String Read_From_Url_Result[]=null,IP_Location_Url="https://www.iplocation.net/?query=[IP]",IP="62.92.63.48",Cookie,Result[],A_Url; public Read_From_Url_Runner(int Id) { this.Id=Id; A_Url=IP_Location_Url.replace("[IP]",IP); Cookie=getIncapsulaCookie(A_Url); Out("Cookie = [ "+Cookie+" ]"); try { Result=call(); // for (int i=0;i Error in data : IP = "+IP); // e.printStackTrace(); } return Read_From_Url_Result; } public static String readUrl(String url,String incapsulaCookie) { StringBuilder response=new StringBuilder(); String USER_AGENT="Mozilla/5.0",inputLine; BufferedReader in=null; try { HttpURLConnection connection=(HttpURLConnection)new URL(url).openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Accept","text/html; charset=UTF-8"); connection.setRequestProperty("User-Agent",USER_AGENT); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestProperty("Cookie",incapsulaCookie); // Set the Incapsula cookie Out(connection.getRequestProperty("Cookie")); in=new BufferedReader(new InputStreamReader(connection.getInputStream())); while ((inputLine=in.readLine())!=null) { response.append(inputLine+"\n"); } in.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (in!=null) in.close(); } catch (Exception ex) { ex.printStackTrace(); } } return response.toString(); } public static String getIncapsulaCookie(String url) { String USER_AGENT="Mozilla/5.0",incapsulaCookie=null,visid=null,incap=null; // Cookies for Incapsula, preserve order BufferedReader in=null; try { HttpURLConnection cookieConnection=(HttpURLConnection)new URL(url).openConnection(); cookieConnection.setRequestMethod("GET"); cookieConnection.setRequestProperty("Accept","text/html; charset=UTF-8"); cookieConnection.setRequestProperty("User-Agent",USER_AGENT); cookieConnection.connect(); for (Entry<String,List> header : cookieConnection.getHeaderFields().entrySet()) { if (header.getKey()!=null && header.getKey().equals("Set-Cookie")) // Incapsula gives you the required cookies { for (String cookieValue : header.getValue()) // Search for the desired cookies { if (cookieValue.contains("visid")) visid=cookieValue.substring(0,cookieValue.indexOf(";")+1); if (cookieValue.contains("incap_ses")) incap=cookieValue.substring(0,cookieValue.indexOf(";")); } } } incapsulaCookie=visid+" "+incap; cookieConnection.disconnect(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (in!=null) in.close(); } catch (Exception ex) { ex.printStackTrace(); } } return incapsulaCookie; } private static void out(String message) { System.out.print(message); } private static void Out(String message) { System.out.println(message); } public static void main(String[] args) { final Read_From_Url_Runner demo=new Read_From_Url_Runner(0); } } 

Pero esto solo obtuvo la primera parte de la respuesta como se muestra a continuación:

enter image description here

Lo que realmente quería obtener es algo como lo siguiente:

enter image description here

Este resultado se obtuvo ejecutando mi progtwig en: ¿Cómo cerrar Javafx?

El problema al que se enfrenta puede ser esencialmente el encabezado de solicitud HTTP , que no configura explícitamente. Los sitios web generalmente se entregan en diferentes representaciones, dependiendo de los atributos en el encabezado HTTP (y la carga), para servir a los clientes móviles o de escritorio de manera adecuada. En cuanto a su código, no establece nada, por lo que envía un encabezado predeterminado , independientemente de la biblioteca que establezca. Si inspecciona el encabezado HTTP concreto que está enviando su navegador, lo más probable es que existan diferencias (como un agente de usuario o encoding, …). Si reconstruye el encabezado en su código, el resultado debería ser el mismo.

Además, puede usar HttpUrlConnection para que pueda configurar o leer fácilmente el encabezado HTTP correspondiente, como en esta publicación SO. De lo contrario, para URLConnection , mira aquí .

Investigación exahustiva

Su método reemplaza una página de error especial, que indica que el sitio web usa características de seguridad adicionales de Incapsula . El sitio que obtienes tiene el siguiente aspecto:

Página de error de Incapsula

Mientras investigaba los encabezados, noté dos cadenas de cookies que deben estar presentes, para que pueda acceder directamente al sitio web, en lugar de la verificación de seguridad:

 visid_incap_...=... incap_ses_..._...=... 

Lo que puede hacer es ingresar a la página de error con una sola solicitud, que le proporciona ambas cadenas de cookies en los encabezados de Set-Cookie . Luego puede solicitar directamente el sitio web con las cadenas de cookies establecidas como visid_incap_...=...; incap_ses_..._...=... visid_incap_...=...; incap_ses_..._...=... Puede ejecutar solicitudes varias veces, hasta que caduque la cookie. Simplemente verifique que la página de error detecte eso. Aquí está el código de trabajo , que obviamente carece de estilo y controles adicionales, pero resuelve su problema. El rest depende de usted.

 public static String getIncapsulaCookie(String url) { String USER_AGENT = "Mozilla/5.0"; BufferedReader in = null; String incapsulaCookie = null; try { HttpURLConnection cookieConnection = (HttpURLConnection) new URL(url).openConnection(); cookieConnection.setRequestMethod("GET"); cookieConnection.setRequestProperty("Accept", "text/html; charset=UTF-8"); cookieConnection.setRequestProperty("User-Agent", USER_AGENT); // Disable 'keep-alive' cookieConnection.setRequestProperty("Connection", "close"); // Cookies for Incapsula, preserve order String visid = null; String incap = null; cookieConnection.connect(); for (Entry> header : cookieConnection .getHeaderFields().entrySet()) { // Incapsula gives you the required cookies if (header.getKey() != null && header.getKey().equals("Set-Cookie")) { // Search for the desired cookies for (String cookieValue : header.getValue()) { if (cookieValue.contains("visid")) { visid = cookieValue.substring(0, cookieValue.indexOf(";") + 1); } if (cookieValue.contains("incap_ses")) { incap = cookieValue.substring(0, cookieValue.indexOf(";")); } } } } incapsulaCookie = visid + " " + incap; // Explicitly disconnect, also essential in this method! cookieConnection.disconnect(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (in != null) in.close(); } catch (Exception ex) { ex.printStackTrace(); } } return incapsulaCookie; } 

Este método extrae la cookie encapsula por usted. Aquí hay una versión modificada de su método, que usa la cookie:

 public static String readUrl(String url, String incapsulaCookie) { StringBuilder response = new StringBuilder(); String USER_AGENT = "Mozilla/5.0", inputLine; BufferedReader in = null; try { HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Accept", "text/html; charset=UTF-8"); connection.setRequestProperty("User-Agent", USER_AGENT); // Set the Incapsula cookie connection.setRequestProperty("Cookie", incapsulaCookie); in = new BufferedReader( new InputStreamReader(connection.getInputStream())); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (in != null) in.close(); } catch (Exception ex) { ex.printStackTrace(); } } return response.toString(); } 

Como he observado, el agente de usuario y otros atributos no parecen importar. Ahora puede llamar a getIncapsulaCookie(String url) una vez o cada vez que quiera una nueva cookie, para obtener la cookie y readUrl(String url, String incapsulaCookie) varias veces para solicitar la página, hasta que caduque la cookie. El resultado es la página HTML completa , como se ve en esta imagen parcial :

enter image description here

Detalles importantes: hay dos comandos esenciales en el getIncapsulaCookie(...) , a saber, cookieConnection.setRequestProperty("Connection", "close"); y cookieConnection.disconnect(); . Ambos son obligatorios , si desea llamar a readUrl(...) inmediatamente después. Si omite estos comandos, la conexión HTTP se mantendrá activa en el lado del servidor después de recibir la cookie y la siguiente llamada a readUrl(...) le devolverá la página incorrecta. Puede probar esto dejando de lado estos comandos y en su lugar llamando a getIncapsulaCookie(...) , luego espere de 5 a 65 segundos y llame a readUrl(...) . Verás que esto también funciona, porque la conexión expira automáticamente. Ver también aquí .