In der Anfangsphase haben wir den Titel unter diesem Link gecrawlt:
http://www.zhihu.com/explore/recommendations
Aber offensichtlich kann diese Seite keine Antwort darauf bekommen.
Eine vollständige Fragenseite würde so aussehen:
http://www.zhihu.com/question/22355264
Bei näherer Betrachtung muss unsere Kapselungsklasse noch weiter gepackt werden. Zum Speichern der Fragenbeschreibung ist mindestens eine Fragebeschreibung erforderlich.
import java.util.ArrayList;
öffentliche Klasse Zhihu {
öffentliche String-Frage; // Frage
public String questionsDescription; // Beschreibung der Frage
public String zhihuUrl;//Webseitenlink
public ArrayList<String> Antworten; // Array zum Speichern aller Antworten
// Konstruktor initialisiert Daten
öffentliches Zhihu() {
Frage = "";
FrageDescription = "";
zhihuUrl = "";
Antworten = new ArrayList<String>();
}
@Override
öffentlicher String toString() {
return „Frage:“ + Frage + „/n“ + „Beschreibung:“ + FrageBeschreibung + „/n“
+ „Link:“ + zhihuUrl + „/nanswer:“ + Antworten + „/n“;
}
}
Wir fügen dem Konstruktor von Zhihu einen Parameter hinzu, um den URL-Wert festzulegen. Da die URL bestimmt wird, können die Beschreibung und die Antwort auf die Frage erfasst werden.
Lassen Sie uns Spiders Methode zum Abrufen von Zhihu-Objekten ändern und nur die URL abrufen:
static ArrayList<Zhihu> GetZhihu(String content) {
// Definieren Sie eine ArrayList vor, um die Ergebnisse zu speichern
ArrayList<Zhihu> results = new ArrayList<Zhihu>();
// Wird verwendet, um die URL abzugleichen, die den Link zur Frage darstellt
Muster urlPattern = Pattern.compile("<h2>.+?question_link.+?href=/"(.+?)/".+?</h2>");
Matcher urlMatcher = urlPattern.matcher(content);
// Ob es ein erfolgreiches passendes Objekt gibt
boolean isFind = urlMatcher.find();
while (isFind) {
//Definieren Sie ein Zhihu-Objekt zum Speichern der erfassten Informationen
Zhihu zhihuTemp = new Zhihu(urlMatcher.group(1));
//Erfolgreiche Matching-Ergebnisse hinzufügen
results.add(zhihuTemp);
// Weiter nach dem nächsten passenden Objekt suchen
isFind = urlMatcher.find();
}
Ergebnisse zurückgeben;
}
Rufen Sie als Nächstes in der Konstruktionsmethode von Zhihu alle detaillierten Daten über die URL ab.
Wir müssen zuerst die URL verarbeiten, denn für einige Antworten lautet ihre URL:
http://www.zhihu.com/question/22355264/answer/21102139
Einige beziehen sich speziell auf das Problem und die URL lautet:
http://www.zhihu.com/question/22355264
Dann brauchen wir natürlich den zweiten Typ, also müssen wir reguläre Regeln verwenden, um den ersten Typ von Link in den zweiten Typ zu schneiden. Dies kann durch das Schreiben einer Funktion in Zhihu erfolgen.
// URL behandeln
boolean getRealUrl(String url) {
// Ändern Sie http://www.zhihu.com/question/22355264/answer/21102139
//Konvertieren zu http://www.zhihu.com/question/22355264
// Ansonsten keine Änderung
Mustermuster = Pattern.compile("question/(.*?)/");
Matcher matcher = pattern.matcher(url);
if (matcher.find()) {
zhihuUrl = "http://www.zhihu.com/question/" + matcher.group(1);
} anders {
return false;
}
return true;
}
Der nächste Schritt besteht darin, die verschiedenen Teile zu besorgen.
Werfen wir zunächst einen Blick auf den Titel:
Fassen Sie diese Klasse einfach in regulärer Form an. Die reguläre Anweisung kann wie folgt geschrieben werden: zm-editable-content/">(.+?)<
Führen Sie es aus, um die Ergebnisse zu sehen:
Autsch, nicht schlecht.
Als nächstes lesen Sie die Problembeschreibung:
Aha, das gleiche Prinzip, nimm die Klasse, denn sie sollte der eindeutige Bezeichner dafür sein.
Überprüfungsmethode: Klicken Sie mit der rechten Maustaste, um den Quellcode der Seite anzuzeigen, und drücken Sie Strg + F, um festzustellen, ob die Seite andere Zeichenfolgen enthält.
Später, nach der Überprüfung, ging etwas wirklich schief:
Die Klasse vor dem Titel und der Beschreibungsinhalt sind gleich.
Dies kann nur durch eine Änderung des regulären Musters wiederhergestellt werden:
// passender Titel
pattern = Pattern.compile("zh-question-title.+?<h2.+?>(.+?)</h2>");
matcher = pattern.matcher(content);
if (matcher.find()) {
Frage = matcher.group(1);
}
// Übereinstimmungsbeschreibung
Muster=Muster
.compile("zh-question-detail.+?<div.+?>(.*?)</div>");
matcher = pattern.matcher(content);
if (matcher.find()) {
questionsDescription = matcher.group(1);
}
Der letzte Schritt besteht darin, eine Schleife zu durchlaufen, um die Antwort zu erhalten:
Vorläufige vorläufige reguläre Anweisung: /answer/content.+?<div.+?>(.*?)</div>
Nach der Änderung des Codes werden wir feststellen, dass die Software deutlich langsamer läuft, da sie jede Webseite besuchen und den Inhalt darauf erfassen muss.
Wenn der Herausgeber beispielsweise 20 Fragen empfiehlt, müssen Sie die Webseite 20 Mal besuchen und die Geschwindigkeit verringert sich.
Probieren Sie es aus, es sieht gut aus:
Okay, lassen wir es erst einmal so. Beim nächsten Mal werden wir weiterhin einige Detailanpassungen vornehmen, wie z. B. Multithreading, lokales Schreiben von IO-Streams usw.
Im Anhang finden Sie den Quellcode des Projekts:
Zhihu.java
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
öffentliche Klasse Zhihu {
öffentliche String-Frage; // Frage
public String questionsDescription; // Beschreibung der Frage
public String zhihuUrl;//Webseitenlink
public ArrayList<String> Antworten; // Array zum Speichern aller Antworten
// Konstruktor initialisiert Daten
public Zhihu(String url) {
//Eigenschaften initialisieren
Frage = "";
FrageDescription = "";
zhihuUrl = "";
Antworten = new ArrayList<String>();
// Bestimmen Sie, ob die URL legal ist
if (getRealUrl(url)) {
System.out.println("crawling" + zhihuUrl);
// Die Details der Frage und Antwort basierend auf der URL abrufen
String-Inhalt = Spider.SendGet(zhihuUrl);
Mustermuster;
Matcher-Matcher;
// passender Titel
pattern = Pattern.compile("zh-question-title.+?<h2.+?>(.+?)</h2>");
matcher = pattern.matcher(content);
if (matcher.find()) {
Frage = matcher.group(1);
}
// Übereinstimmungsbeschreibung
Muster=Muster
.compile("zh-question-detail.+?<div.+?>(.*?)</div>");
matcher = pattern.matcher(content);
if (matcher.find()) {
questionsDescription = matcher.group(1);
}
// Passende Antwort
pattern = Pattern.compile("/answer/content.+?<div.+?>(.*?)</div>");
matcher = pattern.matcher(content);
boolean isFind = matcher.find();
while (isFind) {
antworten.add(matcher.group(1));
isFind = matcher.find();
}
}
}
// Erfassen Sie Ihre eigenen Fragen, Beschreibungen und Antworten basierend auf Ihrer eigenen URL
public boolean getAll() {
return true;
}
// URL behandeln
boolean getRealUrl(String url) {
// Ändern Sie http://www.zhihu.com/question/22355264/answer/21102139
//Konvertieren zu http://www.zhihu.com/question/22355264
// Ansonsten keine Änderung
Mustermuster = Pattern.compile("question/(.*?)/");
Matcher matcher = pattern.matcher(url);
if (matcher.find()) {
zhihuUrl = "http://www.zhihu.com/question/" + matcher.group(1);
} anders {
return false;
}
return true;
}
@Override
öffentlicher String toString() {
return „Frage:“ + Frage + „/n“ + „Beschreibung:“ + FrageBeschreibung + „/n“
+ "Link:" + zhihuUrl + "/nAnswer:" +Antworten.size() + "/n";
}
}
Spider.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
java.net.URL importieren;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
öffentliche Klasse Spider {
statischer String SendGet(String url) {
//Definieren Sie eine Zeichenfolge zum Speichern von Webseiteninhalten
String result = "";
//Definieren Sie einen gepufferten Zeicheneingabestream
BufferedReader in = null;
versuchen {
//String in URL-Objekt konvertieren
URL realUrl = neue URL(url);
// Initialisiere einen Link zu dieser URL
URLConnection-Verbindung = realUrl.openConnection();
// Die eigentliche Verbindung starten
Verbindung.connect();
// Initialisieren Sie den BufferedReader-Eingabestream, um die Antwort der URL zu lesen
in = new BufferedReader(new InputStreamReader(
Connection.getInputStream(), „UTF-8“));
// Wird verwendet, um die Daten jeder erfassten Zeile vorübergehend zu speichern
String-Linie;
while ((line = in.readLine()) != null) {
// Jede erfasste Zeile durchlaufen und im Ergebnis speichern
Ergebnis += Zeile;
}
} Catch (Ausnahme e) {
System.out.println("Ausnahme beim Senden einer GET-Anfrage aufgetreten!" + e);
e.printStackTrace();
}
// Mit „final“ den Eingabestream schließen
Endlich {
versuchen {
if (in != null) {
in.close();
}
} Catch (Ausnahme e2) {
e2.printStackTrace();
}
}
Ergebnis zurückgeben;
}
// Erhalten Sie alle von Redakteuren empfohlenen Zhihu-Inhalte
static ArrayList<Zhihu> GetRecommendations(String content) {
// Definieren Sie eine ArrayList vor, um die Ergebnisse zu speichern
ArrayList<Zhihu> results = new ArrayList<Zhihu>();
// Wird verwendet, um die URL abzugleichen, die den Link zur Frage darstellt
Mustermuster = Muster
.compile("<h2>.+?question_link.+?href=/"(.+?)/".+?</h2>");
Matcher matcher = pattern.matcher(content);
// Ob es ein erfolgreiches passendes Objekt gibt
Boolean isFind = matcher.find();
while (isFind) {
//Definieren Sie ein Zhihu-Objekt zum Speichern der erfassten Informationen
Zhihu zhihuTemp = new Zhihu(matcher.group(1));
//Erfolgreiche Matching-Ergebnisse hinzufügen
results.add(zhihuTemp);
// Weiter nach dem nächsten passenden Objekt suchen
isFind = matcher.find();
}
Ergebnisse zurückgeben;
}
}
Main.java
import java.util.ArrayList;
öffentliche Klasse Main {
public static void main(String[] args) {
// Definieren Sie den Link, der besucht werden soll
String url = "http://www.zhihu.com/explore/recommendations";
//Greifen Sie auf den Link zu und rufen Sie den Seiteninhalt ab
String-Inhalt = Spider.SendGet(url);
// Erhalten Sie Empfehlungen des Herausgebers
ArrayList<Zhihu> myZhihu = Spider.GetRecommendations(content);
// Ergebnisse drucken
System.out.println(myZhihu);
}
}
Das Obige ist die gesamte Aufzeichnung der Antworten von Zhihu. Es ist sehr detailliert.