Dans le dernier épisode, nous avons parlé de la nécessité d'utiliser Java pour créer un robot Zhihu, donc cette fois, nous étudierons comment utiliser le code pour obtenir le contenu de la page Web.
Tout d'abord, si vous n'avez aucune expérience avec HTML, CSS, JS et AJAX, il est recommandé d'aller au W3C (cliquez sur moi, cliquez sur moi) pour en apprendre un peu.
En parlant de HTML, cela implique un problème d'accès GET et d'accès POST.
Si vous ne comprenez pas cet aspect, vous pouvez lire cet article du W3C : « GET vs. POST ».
Aha, je n'entrerai pas dans les détails ici.
Ensuite, nous devons utiliser Java pour explorer le contenu d’une page Web.
À ce moment-là, notre Baidu vous sera utile.
C'est vrai, il n'est plus l'inconnu des testeurs de débit Internet, il est en passe de devenir notre cobaye reptile ! ~
Jetons d’abord un coup d’œil à la page d’accueil de Baidu :
Je pense que tout le monde sait qu'une page comme celle-ci est le résultat du travail conjoint de HTML et CSS.
Nous faisons un clic droit sur la page dans le navigateur et sélectionnons « Afficher le code source de la page » :
C'est vrai, c'est quelque chose comme ça. Il s'agit du code source de la page Baidu.
Notre prochaine tâche consiste à utiliser notre robot pour obtenir la même chose.
Examinons d'abord un code source simple :
importer java.io.* ;
importer java.net.* ;
classe publique Principale {
public static void main (String[] arguments) {
// Définir le lien à visiter
URL de chaîne = "http://www.baidu.com" ;
//Définit une chaîne pour stocker le contenu d'une page Web
Résultat de la chaîne = "" ;
//Définit un flux d'entrée de caractères mis en mémoire tampon
BufferedReader dans = null ;
essayer {
//Convertir la chaîne en objet URL
URL realUrl = nouvelle URL(url);
// Initialise un lien vers cette URL
Connexion URLConnection = realUrl.openConnection();
// Démarre la connexion réelle
connexion.connect();
//Initialisez le flux d'entrée BufferedReader pour lire la réponse de l'URL
in = nouveau BufferedReader (nouveau InputStreamReader (
connexion.getInputStream()));
// Utilisé pour stocker temporairement les données de chaque ligne capturée
Ligne de ficelle ;
while ((line = in.readLine()) != null) {
//Parcourez chaque ligne capturée et stockez-la dans le résultat
résultat += ligne ;
}
} attraper (Exception e) {
System.out.println("Une exception s'est produite lors de l'envoi de la requête GET!" + e);
e.printStackTrace();
}
// Utiliser enfin pour fermer le flux d'entrée
enfin {
essayer {
si (dans != null) {
joindre();
}
} attraper (Exception e2) {
e2.printStackTrace();
}
}
System.out.println(résultat);
}
}
Ce qui précède est une simulation Java de Get accédant à la méthode Main de Baidu.
Vous pouvez l'exécuter pour voir les résultats :
Aha, c'est exactement la même chose que ce que nous avons vu plus tôt dans le navigateur. À ce stade, le robot d’exploration le plus simple est prêt.
Mais un si grand tas de choses ne correspond peut-être pas à ce que je veux. Comment puis-je en tirer ce que je veux ?
Prenons l'exemple du logo à grosse patte de Baidu.
Besoins temporaires :
Obtenez le lien photo de la grande patte du logo Baidu.
Parlons d’abord de la méthode d’affichage du navigateur.
Cliquez avec le bouton droit sur l'image et sélectionnez Inspecter les éléments (Firefox, Google et IE11 ont tous cette fonction, mais les noms sont différents) :
Aha, vous pouvez voir la pauvre balise img entourée de nombreux divs.
Cette src est le lien vers l'image.
Alors, comment fait-on cela en Java ?
Veuillez noter à l'avance que afin de faciliter la démonstration du code, tous les codes ne sont pas encapsulés par classes, veuillez comprendre.
Encapsulons d’abord le code précédent dans une fonction sendGet :
importer java.io.* ;
importer java.net.* ;
classe publique Principale {
Chaîne statique sendGet (URL de chaîne) {
//Définit une chaîne pour stocker le contenu d'une page Web
Résultat de la chaîne = "" ;
//Définit un flux d'entrée de caractères mis en mémoire tampon
BufferedReader dans = null ;
essayer {
//Convertir la chaîne en objet URL
URL realUrl = nouvelle URL(url);
// Initialise un lien vers cette URL
Connexion URLConnection = realUrl.openConnection();
// Démarre la connexion réelle
connexion.connect();
//Initialisez le flux d'entrée BufferedReader pour lire la réponse de l'URL
in = nouveau BufferedReader (nouveau InputStreamReader (
connexion.getInputStream()));
// Utilisé pour stocker temporairement les données de chaque ligne capturée
Ligne de ficelle ;
while ((line = in.readLine()) != null) {
// Parcourez chaque ligne capturée et stockez-la dans le résultat
résultat += ligne ;
}
} attraper (Exception e) {
System.out.println("Une exception s'est produite lors de l'envoi de la requête GET!" + e);
e.printStackTrace();
}
// Utiliser enfin pour fermer le flux d'entrée
enfin {
essayer {
si (dans != null) {
joindre();
}
} attraper (Exception e2) {
e2.printStackTrace();
}
}
renvoyer le résultat ;
}
public static void main (String[] arguments) {
// Définir le lien à visiter
URL de chaîne = "http://www.baidu.com" ;
//Accédez au lien et récupérez le contenu de la page
Résultat de la chaîne = sendGet(url);
System.out.println(résultat);
}
}
Cela a l'air un peu plus ordonné, s'il vous plaît, pardonnez mon trouble obsessionnel-compulsif.
La tâche suivante consiste à trouver le lien vers l'image à partir d'un grand nombre de choses obtenues.
La première méthode à laquelle nous pouvons penser consiste à utiliser la fonction indexof pour rechercher des sous-chaînes String sur le résultat de chaîne du code source de la page.
Oui, cette méthode peut résoudre lentement ce problème, par exemple directement indexOf("src") pour trouver le numéro de série de départ, puis obtenir rapidement le numéro de série de fin.
Cependant, nous ne pouvons pas toujours utiliser cette méthode, car les sandales en paille ne conviennent que pour se promener. Plus tard, il faudra encore couper les jambes prothétiques pour maintenir les têtes.
Veuillez pardonner mon intrusion et continuer.
Alors comment trouver la source de cette image ?
C'est vrai, comme l'a dit le public ci-dessous, une correspondance régulière.
Si des étudiants ne sont pas sûrs des expressions régulières, vous pouvez vous référer à cet article : [Python] Web Crawler (7) : Tutoriel sur les expressions régulières en Python.
En termes simples, les regex sont comme une correspondance.
Par exemple, trois gros hommes se tiennent ici, portant des vêtements rouges, des vêtements bleus et des vêtements verts.
La règle est la suivante : attrapez celui en vert !
Puis il attrapa seul le gros homme vert.
C'est aussi simple que ça.
Cependant, la grammaire régulière est toujours vaste et profonde, et il est inévitable que vous soyez un peu confus lorsque vous entrerez en contact avec elle pour la première fois.
Je recommande à tout le monde un outil de test en ligne régulier : les tests en ligne d’expressions régulières.
Avec la régularité comme arme magique, comment utiliser la régularité en java ?
Regardons d’abord une simple petite prune.
Ah, c'est faux, petite châtaigne.
// Définissez un modèle de style, à l'aide d'expressions régulières, et le contenu à capturer est entre parenthèses
// C'est l'équivalent d'enterrer un piège et il tombera s'il correspond.
Modèle modèle = Pattern.compile("href=/"(.+?)/"");
//Définir un matcher pour la correspondance
Matcher matcher = pattern.matcher("<a href=/"index.html/">Ma page d'accueil</a>");
// si trouvé
si (matcher.find()) {
// affiche le résultat
System.out.println(matcher.group(1));
}
Résultats en cours d'exécution :
index.html
Oui, c'est notre premier code régulier.
Le lien pour récupérer des photos dans cette application doit être à portée de main.
Nous encapsulons la correspondance régulière dans une fonction, puis modifions le code comme suit :
importer java.io.* ;
importer java.net.* ;
importer java.util.regex.* ;
classe publique Principale {
Chaîne statique SendGet (URL de chaîne) {
//Définit une chaîne pour stocker le contenu d'une page Web
Résultat de la chaîne = "" ;
//Définit un flux d'entrée de caractères mis en mémoire tampon
BufferedReader dans = null ;
essayer {
//Convertir la chaîne en objet URL
URL realUrl = nouvelle URL(url);
// Initialise un lien vers cette URL
Connexion URLConnection = realUrl.openConnection();
// Démarre la connexion réelle
connexion.connect();
//Initialisez le flux d'entrée BufferedReader pour lire la réponse de l'URL
in = nouveau BufferedReader (nouveau InputStreamReader (
connexion.getInputStream()));
// Utilisé pour stocker temporairement les données de chaque ligne capturée
Ligne de ficelle ;
while ((line = in.readLine()) != null) {
// Parcourez chaque ligne capturée et stockez-la dans le résultat
résultat += ligne ;
}
} attraper (Exception e) {
System.out.println("Une exception s'est produite lors de l'envoi de la requête GET!" + e);
e.printStackTrace();
}
// Utiliser enfin pour fermer le flux d'entrée
enfin {
essayer {
si (dans != null) {
joindre();
}
} attraper (Exception e2) {
e2.printStackTrace();
}
}
renvoyer le résultat ;
}
chaîne statique RegexString (String targetStr, String patternStr) {
// Définissez un modèle de style, à l'aide d'expressions régulières, et le contenu à capturer est entre parenthèses
// C'est l'équivalent d'enterrer un piège et il tombera s'il correspond.
Modèle de modèle = Pattern.compile(patternStr);
//Définir un matcher pour la correspondance
Matcher matcher = pattern.matcher(targetStr);
// si trouvé
si (matcher.find()) {
// affiche le résultat
retourner matcher.group(1);
}
retour "";
}
public static void main (String[] arguments) {
// Définir le lien à visiter
URL de chaîne = "http://www.baidu.com" ;
//Accédez au lien et récupérez le contenu de la page
Résultat de la chaîne = SendGet(url);
// Utilisez des expressions régulières pour faire correspondre le contenu src de l'image
String imgSrc = RegexString(result, "Grammaire régulière à venir");
// imprimer les résultats
System.out.println(imgSrc);
}
}
Bon, maintenant tout est prêt, juste une grammaire normale !
Alors, quelle déclaration régulière est la plus appropriée ?
Nous avons constaté que tant que nous récupérons la chaîne src="xxxxxx", nous pouvons récupérer l'intégralité du lien src.
Donc une simple instruction régulière : src=/"(.+?)/"
Le code complet est le suivant :
importer java.io.* ;
importer java.net.* ;
importer java.util.regex.* ;
classe publique Principale {
Chaîne statique SendGet (URL de chaîne) {
//Définit une chaîne pour stocker le contenu d'une page Web
Résultat de la chaîne = "" ;
//Définit un flux d'entrée de caractères mis en mémoire tampon
BufferedReader dans = null ;
essayer {
//Convertir la chaîne en objet URL
URL realUrl = nouvelle URL(url);
// Initialise un lien vers cette URL
Connexion URLConnection = realUrl.openConnection();
// Démarre la connexion réelle
connexion.connect();
//Initialisez le flux d'entrée BufferedReader pour lire la réponse de l'URL
in = nouveau BufferedReader (nouveau InputStreamReader (
connexion.getInputStream()));
// Utilisé pour stocker temporairement les données de chaque ligne capturée
Ligne de ficelle ;
while ((line = in.readLine()) != null) {
// Parcourez chaque ligne capturée et stockez-la dans le résultat
résultat += ligne ;
}
} attraper (Exception e) {
System.out.println("Une exception s'est produite lors de l'envoi de la requête GET!" + e);
e.printStackTrace();
}
// Utiliser enfin pour fermer le flux d'entrée
enfin {
essayer {
si (dans != null) {
joindre();
}
} attraper (Exception e2) {
e2.printStackTrace();
}
}
renvoyer le résultat ;
}
chaîne statique RegexString (String targetStr, String patternStr) {
// Définissez un modèle de style, à l'aide d'expressions régulières, et le contenu à capturer est entre parenthèses
// C'est l'équivalent d'enterrer un piège et il tombera s'il correspond.
Modèle de modèle = Pattern.compile(patternStr);
//Définir un matcher pour la correspondance
Matcher matcher = pattern.matcher(targetStr);
// si trouvé
si (matcher.find()) {
// affiche le résultat
retourner matcher.group(1);
}
renvoyer "Rien" ;
}
public static void main (String[] arguments) {
// Définir le lien à visiter
URL de chaîne = "http://www.baidu.com" ;
//Accédez au lien et récupérez le contenu de la page
Résultat de la chaîne = SendGet(url);
// Utilisez des expressions régulières pour faire correspondre le contenu src de l'image
Chaîne imgSrc = RegexString(result, "src=/"(.+?)/"");
// imprimer les résultats
System.out.println(imgSrc);
}
}
De cette façon, nous pouvons utiliser Java pour récupérer le lien vers Baidu LOGO.
Eh bien, même si j'ai passé beaucoup de temps à parler de Baidu, les bases doivent être solidement posées la prochaine fois, nous commencerons officiellement à nous concentrer sur Zhihu ! ~