前期我們抓取標題是在該鏈接下:
http://www.zhihu.com/explore/recommendations
但是顯然這個頁面是無法獲取答案的。
一個完整問題的頁面應該是這樣的鏈接:
http://www.zhihu.com/question/22355264
仔細一看,啊哈我們的封裝類還需要進一步包裝下,至少需要個questionDescription來存儲問題描述:
import java.util.ArrayList;
public class Zhihu {
public String question;// 問題
public String questionDescription;// 問題描述
public String zhihuUrl;// 網頁鏈接
public ArrayList answers;// 存儲所有回答的數組
// 構造方法初始化數據
public Zhihu() {
question = "";
questionDescription = "";
zhihuUrl = "";
answers = new ArrayList();
}
@Override
public String toString() {
return "問題:" + question + "\n" + "描述:" + questionDescription + "\n"
+ "鏈接:" + zhihuUrl + "\n回答:" + answers + "\n";
}
}
我們給知乎的構造函數加上一個參數,用來設定url值,因為url確定了,這個問題的描述和答案也就都能抓到了。
我們將Spider的獲取知乎對象的方法改一下,只獲取url即可:
static ArrayList GetZhihu(String content) {
// 預定義一個ArrayList來存儲結果
ArrayList results = new ArrayList();
// 用來匹配url,也就是問題的鏈接
Pattern urlPattern = Pattern.compile("
.+?question_link.+?href=\"(.+?)\".+?
");Matcher urlMatcher = urlPattern.matcher(content);
// 是否存在匹配成功的對象
boolean isFind = urlMatcher.find();
while (isFind) {
// 定義一個知乎對象來存儲抓取到的信息
Zhihu zhihuTemp = new Zhihu(urlMatcher.group(1));
// 添加成功匹配的結果
results.add(zhihuTemp);
// 繼續查找下一個匹配對象
isFind = urlMatcher.find();
}
return results;
}
接下來,就是在Zhihu的構造方法里面,通過url獲取所有的詳細數據。
我們先要對url進行一個處理,因為有的針對回答的,它的url是:
http://www.zhihu.com/question/22355264/answer/21102139
有的針對問題的,它的url是:
http://www.zhihu.com/question/22355264
那么我們顯然需要的是第二種,所以需要用正則把第一種鏈接裁切成第二種,這個在Zhihu中寫個函數即可。
// 處理url
boolean getRealUrl(String url) {
// 將http://www.zhihu.com/question/22355264/answer/21102139
// 轉化成http://www.zhihu.com/question/22355264
// 否則不變
Pattern pattern = Pattern.compile("question/(.*?)/");
Matcher matcher = pattern.matcher(url);
if (matcher.find()) {
zhihuUrl = "http://www.zhihu.com/question/" + matcher.group(1);
} else {
return false;
}
return true;
}
接下來就是各個部分的獲取工作了。
先看下標題:
正則把握住那個class即可,正則語句可以寫成:zm-editable-content\”>(.+?)<
運行下看看結果:
哎喲不錯哦。
接下來抓取問題描述:
啊哈一樣的原理,抓住class,因為它應該是這個的唯一標識。
驗證方法:右擊查看頁面源代碼,ctrl+F看看頁面中有沒有其他的這個字符串。
后來經過驗證,還真出了問題:
標題和描述內容前面的class是一樣的。
那只能通過修改正則的方式來重新抓取:
// 匹配標題
pattern = Pattern.compile("zh-question-title.+?
(.+?)");matcher = pattern.matcher(content);
if (matcher.find()) {
question = matcher.group(1);
}
// 匹配描述
pattern = Pattern
.compile("zh-question-detail.+?
(.*?)