Un bloque en la página está lleno de contenido por JavaScript y después de cargar la página con Jsoup no hay nada de esa información. ¿Hay alguna manera de obtener también contenido generado por JavaScript al analizar la página con Jsoup
?
No se puede pegar el código de la página aquí, ya que es demasiado largo: http://pastebin.com/qw4Rfqgw
Aquí está el elemento que necesito: <div id='tags_list'></div>
Necesito obtener esta información en Java. Preferiblemente usando Jsoup. Elemento es campo con ayuda de JavaScript:
<div id="tags_list">
<a href="/tagsc0t20099.html" style="font-size:14;">разведчик</a>
<a href="/tagsc0t1879.html" style="font-size:14;">Sr</a>
<a href="/tagsc0t3140.html" style="font-size:14;">стратегический</a>
</div>
Código Java:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
public class Test
{
public static void main( String[] args )
{
try
{
Document Doc = Jsoup.connect( "http://www.bestreferat.ru/referat-32558.html" ).get();
Elements Tags = Doc.select( "#tags_list a" );
for ( Element Tag : Tags )
{
System.out.println( Tag.text() );
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}
}
7 respuestas
JSoup es un analizador HTML , no una especie de motor de navegador integrado. Esto significa que desconoce por completo el contenido que Javascript agrega al DOM después de la carga inicial de la página.
Para obtener acceso a ese tipo de contenido, necesitará un componente de navegador integrado, hay una serie de discusiones sobre SO con respecto a ese tipo de componente, por ejemplo, ¿Hay alguna manera de incrustar un navegador en Java?
Resuelto en mi caso con com.codeborne.phantomjsdriver NOTA: es un código maravilloso.
pom.xml
<dependency>
<groupId>com.codeborne</groupId>
<artifactId>phantomjsdriver</artifactId>
<version> <here goes last version> </version>
</dependency>
PhantomJsUtils.groovy
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.openqa.selenium.WebDriver
import org.openqa.selenium.phantomjs.PhantomJSDriver
class PhantomJsUtils {
private static String filePath = 'data/temp/';
public static Document renderPage(String filePath) {
System.setProperty("phantomjs.binary.path", 'libs/phantomjs') // path to bin file. NOTE: platform dependent
WebDriver ghostDriver = new PhantomJSDriver();
try {
ghostDriver.get(filePath);
return Jsoup.parse(ghostDriver.getPageSource());
} finally {
ghostDriver.quit();
}
}
public static Document renderPage(Document doc) {
String tmpFileName = "$filePath${Calendar.getInstance().timeInMillis}.html";
FileUtils.writeToFile(tmpFileName, doc.toString());
return renderPage(tmpFileName);
}
}
ClassInProject.groovy
Document doc = PhantomJsUtils.renderPage(Jsoup.parse(yourSource))
¿Hay alguna manera de obtener también contenido generado por JavaScript al analizar la página con Jsoup?
Voy a adivinar NO, pensando en lo difícil que sería esto, sin construir un intérprete de JavaScript completo en Java.
Tratar:
Document Doc = Jsoup.connect(url)
.header("Accept-Encoding", "gzip, deflate")
.userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0")
.maxBodySize(0)
.timeout(600000)
.get();
De hecho, hay un "camino"! Tal vez sea más "una solución" que una "forma ... El siguiente código verifica tanto el meta atributo" REFRESH "como el redireccionamiento de JavaScript ... Si alguno de ellos existe, se establece la variable RedirectedUrl
. objetivo ... Entonces puede recuperar la página de destino y continuar ...
String RedirectedUrl=null;
Elements meta = page.select("html head meta");
if (meta.attr("http-equiv").contains("REFRESH")) {
RedirectedUrl = meta.attr("content").split("=")[1];
} else {
if (page.toString().contains("window.location.href")) {
meta = page.select("script");
for (Element script:meta) {
String s = script.data();
if (!s.isEmpty() && s.startsWith("window.location.href")) {
int start = s.indexOf("=");
int end = s.indexOf(";");
if (start>0 && end >start) {
s = s.substring(start+1,end);
s =s.replace("'", "").replace("\"", "");
RedirectedUrl = s.trim();
break;
}
}
}
}
}
... now retrieve the redirected page again...
Después de especificar la agente de usuario, mi problema está resuelto.
https://github.com/jhy/jsoup/issues/287#issuecomment-12769155
Es posible combinando JSoup
con otro marco para interpretar la página web, en mi ejemplo aquí estoy usando HtmlUnit
.
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
...
WebClient webClient = new WebClient();
HtmlPage myPage = webClient.getPage(URL);
Document document = Jsoup.parse(myPage.asXml());
Elements otherLinks = document.select("a[href]");
Preguntas relacionadas
Nuevas preguntas
javascript
Para preguntas sobre la programación en ECMAScript (JavaScript / JS) y sus diversos dialectos / implementaciones (excepto ActionScript). Incluya todas las etiquetas relevantes en su pregunta; por ejemplo, [node.js], [jquery], [json], etc.