Un bloc de la page est rempli de contenu par JavaScript et, après le chargement de la page avec Jsoup, aucune information de ce type n’a été trouvée. Existe-t-il un moyen d’obtenir également du contenu généré par JavaScript lors de l’analyse de page avec Jsoup
?
Impossible de coller le code de page ici, car il est trop long: http://Pastebin.com/qw4Rfqgw
Voici l'élément dont j'ai besoin: <div id='tags_list'></div>
J'ai besoin d'obtenir cette information en Java. De préférence en utilisant Jsoup. L'élément est un champ avec l'aide 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>
Code 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();
}
}
}
JSoup est un analyseur syntaxique HTML, et non une sorte de moteur de navigateur intégré. Cela signifie qu'il ignore totalement le contenu ajouté au DOM par Javascript après le chargement initial de la page.
Pour avoir accès à ce type de contenu, vous aurez besoin d'un composant de navigateur intégré, plusieurs discussions ont eu lieu sur SO concernant ce type de composant, par exemple Y a-t-il un moyen d'intégrer un navigateur en Java?
Résolu dans mon cas avec com.codeborne.phantomjsdriver NOTE: c'est du code groovy.
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))
Vous devez comprendre ce qui se passe:
La façon de comprendre ceci est la suivante: l'analyse du code HTML est simple. L'exécution du code Javascript et la mise à jour du code HTML correspondant sont beaucoup plus complexes et constituent le travail d'un navigateur.
Voici quelques solutions à ce type de problèmes:
Si vous pouvez trouver quels sont les appels Ajax effectués par le code Javascript, c'est-à-dire le chargement de contenu, vous pourrez peut-être utiliser l'URL de ces appels avec Jsoup. Pour ce faire, utilisez les outils de développement de votre navigateur. Mais cela n'est pas garanti pour fonctionner:
Dans ces cas, vous devrez "simuler" le travail d'un navigateur. Heureusement, de tels outils existent. Celui que je connais et que je recommande est PhantomJS . Cela fonctionne avec Javascript, et vous auriez besoin de le lancer à partir de Java en lançant un nouveau processus. Si vous souhaitez vous en tenir à Java, cet article répertorie certaines alternatives Java.
J'ai fait il y a un "chemin"! Il s’agit peut-être plus d’une solution de contournement que d’une "manière ... Le code ci-dessous vérifie à la fois le méta-attribut" REFRESH "et les redirections javascript ... Si l’un d’eux existe, la variable RedirectedUrl
est définie. Vous connaissez donc votre cible ... Ensuite, vous pouvez récupérer la page cible et continuer ...
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...
Après avoir spécifié l'agent utilisateur, mon problème est résolu.
https://github.com/jhy/jsoup/issues/287#issuecomment-12769155
Existe-t-il un moyen d'obtenir également du contenu généré par javascript lors de l'analyse d'une page avec Jsoup?
Je vais deviner NON, en pensant à la difficulté que cela pourrait être, sans construire un interpréteur javascript complet en Java.