首頁  >  文章  >  Java  >  零基礎寫Java知乎爬蟲之抓取知乎答案

零基礎寫Java知乎爬蟲之抓取知乎答案

黄舟
黄舟原創
2016-12-24 11:41:341429瀏覽

前期我們抓取標題是在該連結下:

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<String> answers;// 存储所有回答的数组
 // 构造方法初始化数据
 public Zhihu() {
  question = "";
  questionDescription = "";
  zhihuUrl = "";
  answers = new ArrayList<String>();
 }
 @Override
 public String toString() {
  return "问题:" + question + "\n" + "描述:" + questionDescription + "\n"
    + "链接:" + zhihuUrl + "\n回答:" + answers + "\n";
 }
}

我們為知乎的建構子加上一個參數,用來設定url值,因為url確定了,這個問題的描述和答案也就都能抓到了。

我們將Spider的獲取知乎對象的方法改一下,只獲取url即可:

static ArrayList<Zhihu> GetZhihu(String content) {
  // 预定义一个ArrayList来存储结果
  ArrayList<Zhihu> results = new ArrayList<Zhihu>();
  // 用来匹配url,也就是问题的链接
  Pattern urlPattern = Pattern.compile("<h2>.+?question_link.+?href=\"(.+?)\".+?</h2>");
  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;
 }

接下來就是各個部分的獲取工作了。

先看下標題:

零基礎寫Java知乎爬蟲之抓取知乎答案

正則把握住那個class即可,正則語句可以寫成:zm-editable-content">(.+?)

運行下看看結果:

零基礎寫Java知乎爬蟲之抓取知乎答案

零基礎寫Java知乎爬蟲之抓取知乎答案

零基礎寫Java知乎爬蟲之抓取知乎答案


哎喲好哦。 ,ctrl+F看看頁面中有沒有其他的這個字串。只能透過修改正規的方式來重新抓取:

// 匹配标题
   pattern = Pattern.compile("zh-question-title.+?<h2.+?>(.+?)</h2>");
   matcher = pattern.matcher(content);
   if (matcher.find()) {
    question = matcher.group(1);
   }
   // 匹配描述
   pattern = Pattern
     .compile("zh-question-detail.+?<div.+?>(.*?)</div>");
   matcher = pattern.matcher(content);
   if (matcher.find()) {
    questionDescription = matcher.group(1);
   }

最後就是循環抓取答案了:零基礎寫Java知乎爬蟲之抓取知乎答案

初步暫定正則語句:/answer/content.+?

(.* ?)

改下程式碼之後我們會發現軟體運作的速度明顯變慢了,因為他需要造訪每個網頁並且把上面的內容抓下來。那就需要訪問網頁20次,速度也就慢下來了。線程,IO流寫入本地等等。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn