初期段階では、次のリンクの下でタイトルをクロールしました。
http://www.zhihu.com/explore/recommendations
しかし明らかにこのページでは答えが得られません。
完全な質問ページは次のようになります。
http://www.zhihu.com/question/22355264
よく見てみると、ああ、質問の説明を保存するには、カプセル化クラスをさらにパッケージ化する必要があります。
java.util.ArrayListをインポートします。
パブリッククラス Zhihu {
public String 質問 // 質問;
public String questionDescription // 質問の説明;
public String zhihuUrl;//Web ページのリンク
public ArrayList<String> 回答 // すべての回答を格納する配列。
// コンストラクターがデータを初期化します
public Zhihu() {
質問 = "";
質問の説明 = "";
zhihuUrl = "";
答え = 新しい ArrayList<String>();
}
@オーバーライド
public String toString() {
return "質問:" + 質問 + "/n" + "説明:" + questionDescription + "/n"
+ "リンク:" + zhihuUrl + "/nanswer:" + 回答 + "/n";
}
}
Zhihu のコンストラクターに URL 値を設定するパラメーターを追加します。URL が決定されるため、質問に対する説明と回答を取得できます。
Spider の Zhihu オブジェクトの取得方法を変更して、URL のみを取得してみましょう。
static ArrayList<Zhihu> GetZhihu(String content) {
// 結果を保存するための ArrayList を事前定義します
ArrayList<Zhihu> 結果 = new ArrayList<Zhihu>();
// 質問へのリンクである URL を照合するために使用されます
パターン urlPattern = Pattern.compile("<h2>.+?question_link.+?href=/"(.+?)/".+?</h2>");
マッチャー urlMatcher = urlPattern.matcher(content);
// 一致するオブジェクトがあるかどうか
ブール値 isFind = urlMatcher.find();
while (isFind) {
// キャプチャした情報を保存する Zhihu オブジェクトを定義します
Zhihu zhihuTemp = new Zhihu(urlMatcher.group(1));
// 成功した一致結果を追加します
results.add(zhihuTemp);
// 次に一致するオブジェクトの検索を続けます
isFind = urlMatcher.find();
}
結果を返します。
}
次に、Zhihu の構築方法では、URL を通じてすべての詳細データを取得します。
一部の回答では、その URL が次のとおりであるため、最初に URL を処理する必要があります。
http://www.zhihu.com/question/22355264/answer/21102139
いくつかは問題に固有のもので、その URL は次のとおりです。
http://www.zhihu.com/question/22355264
次に、明らかに必要なのは 2 番目のタイプなので、通常のルールを使用して最初のタイプのリンクを 2 番目のタイプに分割する必要があります。これは、Zhihu で関数を記述することで実行できます。
// ハンドルURL
ブール値 getRealUrl(String url) {
// 変更 http://www.zhihu.com/question/22355264/answer/21102139
// http://www.zhihu.com/question/22355264 に変換します
// それ以外の場合は変更なし
パターン pattern = Pattern.compile("question/(.*?)/");
マッチャー matcher = pattern.matcher(url);
if (matcher.find()) {
zhihuUrl = "http://www.zhihu.com/question/" + matcher.group(1);
} それ以外 {
false を返します。
}
true を返します。
}
次のステップは、さまざまな部品を入手することです。
まずはタイトルを見てみましょう:
そのクラスを通常の形式で理解するだけです。通常のステートメントは次のように記述できます。 zm-editable-content/">(.+?)<
実行して結果を確認します。
ああ、悪くない。
次に問題の説明を取得します。
ああ、同じ原理で、クラスを取得します。これは、これの一意の識別子である必要があるためです。
確認方法: 右クリックしてページのソース コードを表示し、ctrl+F を押してページ内に他の文字列があるかどうかを確認します。
その後、検証したところ、実際に問題が発生しました。
タイトルの前のクラスと説明内容は同じです。
これは、通常のパターンを変更することによってのみ再キャプチャできます。
// タイトルに一致
pattern = Pattern.compile("zh-question-title.+?<h2.+?>(.+?)</h2>");
matcher = pattern.matcher(コンテンツ);
if (matcher.find()) {
質問 = matcher.group(1);
}
// 説明の一致
pattern=パターン
.compile("zh-question-detail.+?<div.+?>(.*?)</div>");
matcher = pattern.matcher(コンテンツ);
if (matcher.find()) {
questionDescription = matcher.group(1);
}
最後にループして答えを取得します。
暫定的な暫定的な通常のステートメント: /answer/content.+?<div.+?>(.*?)</div>
コードを変更すると、ソフトウェアは各 Web ページにアクセスしてコンテンツをキャプチャする必要があるため、動作が大幅に遅くなることがわかります。
たとえば、編集者が推奨する問題が 20 問ある場合、Web ページに 20 回アクセスする必要があり、速度が遅くなります。
試してみてください、良さそうです:
さて、今回はこのままにしておきます~次回はマルチスレッド化やIOストリームのローカル書き込みなど細かい調整を続けていきます。
プロジェクトのソースコードを添付します。
Zhihu.java
java.util.ArrayListをインポートします。
java.util.regex.Matcherをインポートします。
java.util.regex.Patternをインポートします。
パブリッククラス Zhihu {
public String 質問 // 質問;
public String questionDescription // 質問の説明;
public String zhihuUrl;//Web ページのリンク
public ArrayList<String> 回答 // すべての回答を格納する配列。
// コンストラクターがデータを初期化します
public Zhihu(文字列 URL) {
//プロパティを初期化する
質問 = "";
質問の説明 = "";
zhihuUrl = "";
答え = 新しい ArrayList<String>();
// URL が正当かどうかを判断します
if (getRealUrl(url)) {
System.out.println("クロール" + zhihuUrl);
// URLに基づいて質問と回答の詳細を取得します
文字列コンテンツ = Spider.SendGet(zhihuUrl);
パターンパターン;
マッチャーマッチャー。
// タイトルに一致
pattern = Pattern.compile("zh-question-title.+?<h2.+?>(.+?)</h2>");
matcher = pattern.matcher(コンテンツ);
if (matcher.find()) {
質問 = matcher.group(1);
}
// 説明の一致
pattern=パターン
.compile("zh-question-detail.+?<div.+?>(.*?)</div>");
matcher = pattern.matcher(コンテンツ);
if (matcher.find()) {
questionDescription = matcher.group(1);
}
// 答え合わせ
pattern = Pattern.compile("/answer/content.+?<div.+?>(.*?)</div>");
matcher = pattern.matcher(コンテンツ);
ブール値 isFind = matcher.find();
while (isFind) {
Answers.add(matcher.group(1));
isFind = matcher.find();
}
}
}
// 独自の URL に基づいて独自の質問、説明、回答を取得します
public boolean getAll() {
true を返します。
}
// ハンドルURL
ブール値 getRealUrl(String url) {
// 変更 http://www.zhihu.com/question/22355264/answer/21102139
// http://www.zhihu.com/question/22355264 に変換します
// それ以外の場合は変更なし
パターン pattern = Pattern.compile("question/(.*?)/");
マッチャー matcher = pattern.matcher(url);
if (matcher.find()) {
zhihuUrl = "http://www.zhihu.com/question/" + matcher.group(1);
} それ以外 {
false を返します。
}
true を返します。
}
@オーバーライド
public String toString() {
return "質問:" + 質問 + "/n" + "説明:" + questionDescription + "/n"
+ "リンク:" + zhihuUrl + "/nAnswer:" + Answers.size() + "/n";
}
}
スパイダー.java
java.io.BufferedReaderをインポートします。
インポートjava.io.InputStreamReader;
java.net.URLをインポートします。
java.net.URLConnectionをインポートします。
java.util.ArrayListをインポートします。
java.util.regex.Matcherをインポートします。
java.util.regex.Patternをインポートします。
パブリッククラス Spider {
静的 String SendGet(String url) {
// Web ページのコンテンツを保存する文字列を定義します
文字列結果 = "";
//バッファリングされた文字入力ストリームを定義する
BufferedReader の = null;
試す {
//文字列をURLオブジェクトに変換
URL realUrl = 新しい URL(url);
// その URL へのリンクを初期化します
URLConnection 接続 = realUrl.openConnection();
// 実際の接続を開始します
接続.connect();
// URL の応答を読み取るために BufferedReader 入力ストリームを初期化します
in = new BufferedReader(new InputStreamReader(
connection.getInputStream(), "UTF-8"));
// キャプチャされた各行のデータを一時的に保存するために使用されます
文字列行;
while ((line = in.readLine()) != null) {
// キャプチャされた各行を走査し、結果に格納します
結果 += 行;
}
} catch (例外 e) {
System.out.println("GET リクエストの送信中に例外が発生しました!" + e);
e.printStackTrace();
}
// 入力ストリームを閉じるには、finally を使用します。
ついに {
試す {
if (in != null) {
in.close();
}
} キャッチ (例外 e2) {
e2.printStackTrace();
}
}
結果を返します。
}
// 編集者が推奨する Zhihu コンテンツをすべて取得します
static ArrayList<Zhihu> GetRecommendations(String content) {
// 結果を保存するための ArrayList を事前定義します
ArrayList<Zhihu> 結果 = new ArrayList<Zhihu>();
// 質問へのリンクである URL を照合するために使用されます
パターンパターン=パターン
.compile("<h2>.+?question_link.+?href=/"(.+?)/".+?</h2>");
マッチャー matcher = pattern.matcher(content);
// 一致するオブジェクトがあるかどうか
ブール値 isFind = matcher.find();
while (isFind) {
// キャプチャした情報を保存する Zhihu オブジェクトを定義します
Zhihu zhihuTemp = new Zhihu(matcher.group(1));
// 成功した一致結果を追加します
results.add(zhihuTemp);
// 次に一致するオブジェクトの検索を続けます
isFind = matcher.find();
}
結果を返します。
}
}
メイン.java
java.util.ArrayListをインポートします。
パブリッククラス Main {
public static void main(String[] args) {
// アクセスするリンクを定義します
文字列 URL = "http://www.zhihu.com/explore/recommendations";
// リンクにアクセスしてページのコンテンツを取得します
文字列コンテンツ = Spider.SendGet(url);
// エディターの推奨事項を取得する
ArrayList<Zhihu> myZhihu = Spider.GetRecommendations(content);
// 結果を出力する
System.out.println(myZhihu);
}
}
上記はZhihuの回答を取得した全体の記録です。必要な友達はそれを参照してください。