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();
        }
    }
}
30
Eugene 20 sep. 2011 a las 21:01

7 respuestas

La mejor respuesta

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?

24
Community 23 may. 2017 a las 12:10

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))
14
iluhin 12 oct. 2017 a las 10:45

¿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.

0
Zoe 6 dic. 2018 a las 15:57

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();
-2
Tiger-222 2 jul. 2017 a las 14:09

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...
1
salihcenap 23 nov. 2013 a las 10:18

Después de especificar la agente de usuario, mi problema está resuelto.

https://github.com/jhy/jsoup/issues/287#issuecomment-12769155

0
emon 6 dic. 2018 a las 14:27

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]");
0
res 16 ene. 2020 a las 09:23