Zhihu est une véritable communauté de questions/réponses en ligne avec une ambiance communautaire conviviale, rationnelle et sérieuse qui met en relation des élites de tous horizons. Ils partagent leurs connaissances professionnelles, leur expérience et leurs idées et fournissent en permanence des informations de haute qualité pour l'Internet chinois.
Tout d’abord, passez trois à cinq minutes à concevoir un logo =. =En tant que programmeur, j'ai toujours eu à cœur d'être un artiste !
D'accord, c'est un petit bricolage, alors je vais me contenter de ça pour le moment.
Ensuite, nous avons commencé à fabriquer le robot d'exploration de Zhihu.
Tout d’abord, déterminez le premier objectif : la recommandation de l’éditeur.
Lien Web : http://www.zhihu.com/explore/recommendations
Nous avons légèrement modifié le dernier code pour obtenir dans un premier temps la possibilité d'obtenir le contenu de la page :
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.zhihu.com/explore/recommendations" ;
//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, "src=/"(.+?)/"");
// imprimer les résultats
System.out.println(résultat);
}
}
Il n'y a aucun problème après l'exécution. L'étape suivante est un problème de correspondance régulier.
Tout d’abord, répondons à toutes les questions sur cette page.
Faites un clic droit sur le titre et inspectez l'élément :
Aha, vous pouvez voir que le titre est en fait une balise a, qui est un lien hypertexte, et ce qui peut être distingué des autres hyperliens devrait être la classe, qui est le sélecteur de classe.
Ainsi, notre déclaration habituelle apparaît : question_link.+?href=/"(.+?)/"
Appelez la fonction RegexString et transmettez-lui les paramètres :
public static void main (String[] arguments) {
// Définir le lien à visiter
URL de chaîne = "http://www.zhihu.com/explore/recommendations" ;
//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, "question_link.+?>(.+?)<");
// imprimer les résultats
System.out.println(imgSrc);
}
Ah ha, vous pouvez voir que nous avons réussi à capturer un titre (attention, un seul) :
Attends une minute, c'est quoi tout ce bordel ? !
Ne soyez pas nerveux =. = Ce sont juste des caractères tronqués.
Pour les problèmes d'encodage, veuillez consulter : Jeu de caractères HTML
De manière générale, les encodages courants offrant une meilleure prise en charge du chinois sont les encodages UTF-8, GB2312 et GBK.
La page Web peut définir le codage de la page Web via le jeu de caractères de la balise méta, par exemple :
<meta charset="utf-8" />
Faisons un clic droit pour afficher le code source de la page :
Comme vous pouvez le voir, Zhihu utilise le codage UTF-8.
Ici, je vais vous expliquer la différence entre afficher le code source de la page et inspecter les éléments.
L'affichage du code source de la page affiche tout le code de la page entière. Il n'est pas formaté selon les balises HTML. Cela équivaut à afficher directement le code source. Cette méthode est plus utile pour afficher les informations de la page Web entière, par exemple. méta.
Inspecter l'élément, ou certains navigateurs l'appellent view element, qui consiste à afficher l'élément sur lequel vous cliquez avec le bouton droit, comme un div ou un img. Il est plus approprié pour afficher les attributs et les balises d'un objet individuellement.
Bon, maintenant nous savons que le problème réside dans l'encodage, l'étape suivante consiste à convertir l'encodage du contenu capturé.
L'implémentation en java est très simple, il suffit de spécifier la méthode d'encodage dans InputStreamReader :
//Initialisez le flux d'entrée BufferedReader pour lire la réponse de l'URL
in = nouveau BufferedReader (nouveau InputStreamReader (
connexion.getInputStream(),"UTF-8"));
Si vous exécutez à nouveau le programme à ce moment-là, vous constaterez que le titre peut s'afficher normalement :
D'ACCORD! très bien!
Mais maintenant il n’y a qu’un seul titre, il nous faut tous les titres.
Nous modifions légèrement l'expression régulière et stockons les résultats recherchés dans une ArrayList :
importer java.io.* ;
importer java.net.* ;
importer java.util.ArrayList ;
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(), "UTF-8"));
// 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 ;
}
static ArrayList<String> RegexString(String targetStr, String patternStr) {
// Prédéfinir une ArrayList pour stocker les résultats
ArrayList<String> résultats = new ArrayList<String>();
// Définissez un modèle de style, à l'aide d'expressions régulières, et le contenu à capturer est entre parenthèses
Modèle de modèle = Pattern.compile(patternStr);
//Définir un matcher pour la correspondance
Matcher matcher = pattern.matcher(targetStr);
// si trouvé
booléen isFind = matcher.find();
// Utilisez une boucle pour rechercher et remplacer tous les kelvins dans la phrase et ajouter le contenu à sb
tandis que (estFind) {
//Ajouter des résultats de correspondance réussis
results.add(matcher.group(1));
// Continuer à trouver le prochain objet correspondant
isFind = matcher.find();
}
renvoyer les résultats ;
}
public static void main (String[] arguments) {
// Définir le lien à visiter
URL de chaîne = "http://www.zhihu.com/explore/recommendations" ;
//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
ArrayList<String> imgSrc = RegexString(result, "question_link.+?>(.+?)<");
// imprimer les résultats
System.out.println(imgSrc);
}
}
Cela correspondra à tous les résultats (parce que l'ArrayList est imprimé directement, il y aura des crochets et des virgules) :
OK, c'est la première étape du robot d'exploration Zhihu.
Mais nous pouvons voir qu’il n’existe aucun moyen de capturer ainsi toutes les questions et réponses.
Nous devons concevoir une classe d'encapsulation Zhihu pour stocker tous les objets capturés.
Code source de Zhihu.java :
importer java.util.ArrayList ;
classe publique Zhihu {
question de chaîne publique ; // question
chaîne publique zhihuUrl ; // Lien vers une page Web
public ArrayList<String> réponses ; // Tableau pour stocker toutes les réponses
// Le constructeur initialise les données
public Zhihu() {
question = "" ;
zhihuUrl = "";
réponses = new ArrayList<String>();
}
@Outrepasser
chaîne publique versChaîne() {
return "Question :" + question + "/nLink :" + zhihuUrl + "/nAnswer :" + réponses + "/n" ;
}
}
Créez une nouvelle classe Spider pour stocker certaines fonctions couramment utilisées des robots d'exploration.
Code source de Spider.java :
importer java.io.BufferedReader ;
importer java.io.InputStreamReader ;
importer java.net.URL ;
importer java.net.URLConnection ;
importer java.util.ArrayList ;
importer java.util.regex.Matcher ;
importer java.util.regex.Pattern ;
classe publique Araignée {
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(), "UTF-8"));
// 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 ;
}
static ArrayList<Zhihu> GetZhihu(Contenu de la chaîne) {
// Prédéfinir une ArrayList pour stocker les résultats
ArrayList<Zhihu> résultats = new ArrayList<Zhihu>();
// Utilisé pour faire correspondre les titres
Modèle questionPattern = Pattern.compile("question_link.+?>(.+?)<");
Matcher questionMatcher = questionPattern.matcher(content);
// Utilisé pour correspondre à l'url, qui est le lien vers la question
Modèle urlPattern = Pattern.compile("question_link.+?href=/"(.+?)/"");
Matcher urlMatcher = urlPattern.matcher(content);
// La question et le lien doivent correspondre
booléen isFind = questionMatcher.find() && urlMatcher.find();
tandis que (estFind) {
//Définissez un objet Zhihu pour stocker les informations capturées
Zhihu zhuhuTemp = new Zhihu();
zhuhuTemp.question = questionMatcher.group(1);
zhuhuTemp.zhihuUrl = "http://www.zhihu.com" + urlMatcher.group(1);
//Ajouter des résultats de correspondance réussis
results.add(zhuhuTemp);
// Continuer à trouver le prochain objet correspondant
isFind = questionMatcher.find() && urlMatcher.find();
}
renvoyer les résultats ;
}
}
La dernière méthode principale est responsable de l'appel.
importer java.util.ArrayList ;
classe publique Principale {
public static void main (String[] arguments) {
// Définir le lien à visiter
URL de chaîne = "http://www.zhihu.com/explore/recommendations" ;
//Accédez au lien et récupérez le contenu de la page
Contenu de la chaîne = Spider.SendGet(url);
// Récupère tous les objets Zhihu sur cette page
ArrayList<Zhihu> myZhihu = Spider.GetZhihu(content);
// imprimer les résultats
System.out.println(myZhihu);
}
}
Ok, c'est tout. Exécutez-le et voyez les résultats :
Bons résultats.
L'étape suivante consiste à accéder au lien et à obtenir toutes les réponses.
Nous le présenterons la prochaine fois.
D'accord, ce qui précède est une brève introduction à l'ensemble du processus d'utilisation de Java pour capturer le contenu recommandé par les éditeurs de Zhihu. Il est très détaillé et facile à comprendre. Les amis dans le besoin peuvent s'y référer et se développer librement, haha.