亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

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

2019-11-26 15:21:50
字體:
來源:轉載
供稿:網友

前期我們抓取標題是在該鏈接下:

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 = "  } else {
   return false;
  }
  return true;
 }

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

先看下標題:

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

運行下看看結果:

哎喲不錯哦。

接下來抓取問題描述:

啊哈一樣的原理,抓住class,因為它應該是這個的唯一標識。

驗證方法:右擊查看頁面源代碼,ctrl+F看看頁面中有沒有其他的這個字符串。

后來經過驗證,還真出了問題:

標題和描述內容前面的class是一樣的。

那只能通過修改正則的方式來重新抓取:

// 匹配標題
   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);
   }

最后就是循環抓取答案了:

初步暫定正則語句:/answer/content.+?<div.+?>(.*?)</div>

改下代碼之后我們會發現軟件運行的速度明顯變慢了,因為他需要訪問每個網頁并且把上面的內容抓下來。

比如說編輯推薦有20個問題,那么就需要訪問網頁20次,速度也就慢下來了。

試驗一下,看上去效果不錯:


OK,那就先這樣好了~下次繼續進行一些細節的調整,比如多線程,IO流寫入本地等等。

附項目源碼:

Zhihu.java

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Zhihu {
 public String question;// 問題
 public String questionDescription;// 問題描述
 public String zhihuUrl;// 網頁鏈接
 public ArrayList<String> answers;// 存儲所有回答的數組
 // 構造方法初始化數據
 public Zhihu(String url) {
  // 初始化屬性
  question = "";
  questionDescription = "";
  zhihuUrl = "";
  answers = new ArrayList<String>();
  // 判斷url是否合法
  if (getRealUrl(url)) {
   System.out.println("正在抓取" + zhihuUrl);
   // 根據url獲取該問答的細節
   String content = Spider.SendGet(zhihuUrl);
   Pattern pattern;
   Matcher matcher;
   // 匹配標題
   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);
   }
   // 匹配答案
   pattern = Pattern.compile("/answer/content.+?<div.+?>(.*?)</div>");
   matcher = pattern.matcher(content);
   boolean isFind = matcher.find();
   while (isFind) {
    answers.add(matcher.group(1));
    isFind = matcher.find();
   }
  }
 }
 // 根據自己的url抓取自己的問題和描述和答案
 public boolean getAll() {
  return true;
 }
 // 處理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 = "  } else {
   return false;
  }
  return true;
 }
 @Override
 public String toString() {
  return "問題:" + question + "/n" + "描述:" + questionDescription + "/n"
    + "鏈接:" + zhihuUrl + "/n回答:" + answers.size() + "/n";
 }
}

Spider.java

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Spider {
 static String SendGet(String url) {
  // 定義一個字符串用來存儲網頁內容
  String result = "";
  // 定義一個緩沖字符輸入流
  BufferedReader in = null;
  try {
   // 將string轉成url對象
   URL realUrl = new URL(url);
   // 初始化一個鏈接到那個url的連接
   URLConnection connection = realUrl.openConnection();
   // 開始實際的連接
   connection.connect();
   // 初始化 BufferedReader輸入流來讀取URL的響應
   in = new BufferedReader(new InputStreamReader(
     connection.getInputStream(), "UTF-8"));
   // 用來臨時存儲抓取到的每一行的數據
   String line;
   while ((line = in.readLine()) != null) {
    // 遍歷抓取到的每一行并將其存儲到result里面
    result += line;
   }
  } catch (Exception e) {
   System.out.println("發送GET請求出現異常!" + e);
   e.printStackTrace();
  }
  // 使用finally來關閉輸入流
  finally {
   try {
    if (in != null) {
     in.close();
    }
   } catch (Exception e2) {
    e2.printStackTrace();
   }
  }
  return result;
 }
 // 獲取所有的編輯推薦的知乎內容
 static ArrayList<Zhihu> GetRecommendations(String content) {
  // 預定義一個ArrayList來存儲結果
  ArrayList<Zhihu> results = new ArrayList<Zhihu>();
  // 用來匹配url,也就是問題的鏈接
  Pattern pattern = Pattern
    .compile("<h2>.+?question_link.+?href=/"(.+?)/".+?</h2>");
  Matcher matcher = pattern.matcher(content);
  // 是否存在匹配成功的對象
  Boolean isFind = matcher.find();
  while (isFind) {
   // 定義一個知乎對象來存儲抓取到的信息
   Zhihu zhihuTemp = new Zhihu(matcher.group(1));
   // 添加成功匹配的結果
   results.add(zhihuTemp);
   // 繼續查找下一個匹配對象
   isFind = matcher.find();
  }
  return results;
 }
}

Main.java

import java.util.ArrayList;
public class Main {
 public static void main(String[] args) {
  // 定義即將訪問的鏈接
  String url = "
  // 訪問鏈接并獲取頁面內容
  String content = Spider.SendGet(url);
  // 獲取編輯推薦
  ArrayList<Zhihu> myZhihu = Spider.GetRecommendations(content);
  // 打印結果
  System.out.println(myZhihu);
 }
}

以上就是抓取知乎答案的全部記錄,非常的詳盡,有需要的朋友可以參考下

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品国产三级国产aⅴ浪潮| 亚洲美女久久久| 影音先锋欧美精品| 欧美韩国理论所午夜片917电影| 在线亚洲午夜片av大片| 亚洲国产精品久久91精品| 欧美午夜xxx| 国产主播精品在线| 91人成网站www| 国内精品久久影院| 精品国偷自产在线| 日韩在线播放一区| 欧美夫妻性生活视频| 国产日韩欧美在线观看| 精品国产拍在线观看| 国产精品入口日韩视频大尺度| 国外成人在线直播| 精品久久国产精品| 亚洲人成在线观看| 久久99久国产精品黄毛片入口| 欧美日韩久久久久| 欧美肥臀大乳一区二区免费视频| 亚洲无线码在线一区观看| 欧美成人激情视频| 国产热re99久久6国产精品| 国产精品久久久久久久久久三级| 亚洲精品白浆高清久久久久久| 亚洲成人av片| 欧美成人免费全部观看天天性色| 国产精品扒开腿爽爽爽视频| 最近免费中文字幕视频2019| 亚洲欧洲高清在线| 亚洲mm色国产网站| 日本sm极度另类视频| 国产区精品视频| 精品无人区太爽高潮在线播放| 久久精品久久久久电影| 精品国产乱码久久久久久婷婷| 成人免费视频在线观看超级碰| 久久亚洲综合国产精品99麻豆精品福利| 国产精品视频xxx| 久久精品成人动漫| 欧美精品videossex性护士| 日本不卡免费高清视频| 黑人精品xxx一区| 亚洲色图第三页| 日韩欧美精品网址| 国产精品欧美一区二区| 原创国产精品91| 精品视频久久久久久| 欧美又大粗又爽又黄大片视频| 欧美性xxxxhd| 亚洲国产天堂久久综合网| 91精品国产综合久久香蕉的用户体验| 18一19gay欧美视频网站| 欧美尺度大的性做爰视频| 亚洲综合社区网| 久久久女女女女999久久| 亚洲老头同性xxxxx| 亚洲男人天堂手机在线| 欧美亚洲成人精品| 亚洲欧美日韩视频一区| 日韩免费高清在线观看| 亚洲国产高潮在线观看| 亚洲精品国产精品乱码不99按摩| 91在线无精精品一区二区| 久久久久久久电影一区| 国产香蕉97碰碰久久人人| 亚洲va欧美va国产综合剧情| 国产欧美精品xxxx另类| 亚洲白虎美女被爆操| 粉嫩av一区二区三区免费野| 亚洲性xxxx| 尤物tv国产一区| 欧美激情在线观看视频| 亚洲免费视频一区二区| 亚洲а∨天堂久久精品9966| 一色桃子一区二区| 欧美中文字幕第一页| 亚洲欧美另类自拍| 国产精品永久在线| 日韩欧美亚洲范冰冰与中字| 欧美福利视频网站| 91九色国产视频| 亚洲乱码国产乱码精品精天堂| 久久久久久亚洲精品| 欧美激情亚洲一区| 亚洲国产又黄又爽女人高潮的| 一区二区三区动漫| 亚洲男人av在线| 欧美在线视频免费观看| 欧美性xxxxx极品娇小| 亚洲综合在线播放| 国产成人精品视| 亚洲一区二区久久久| 国产精品久久久久久亚洲影视| 国产精品白嫩初高中害羞小美女| 欧美性xxxxx极品| 欧美黑人国产人伦爽爽爽| 狠狠色噜噜狠狠狠狠97| 91精品国产高清久久久久久久久| 久久久久这里只有精品| 懂色av中文一区二区三区天美| 在线精品高清中文字幕| 日韩中文字幕在线播放| 亚洲va男人天堂| 国产成人在线一区| 亚洲欧洲中文天堂| 色与欲影视天天看综合网| 国外日韩电影在线观看| 91国产精品视频在线| 亚洲免费伊人电影在线观看av| 久久噜噜噜精品国产亚洲综合| 欧洲成人免费视频| 久久久之久亚州精品露出| 欧美福利在线观看| 欧美成人在线免费| 精品中文字幕在线观看| 亚洲男人7777| 欧美一区二区色| 97精品在线观看| 日本中文字幕不卡免费| 深夜成人在线观看| 精品一区二区电影| 91高清在线免费观看| 97精品久久久中文字幕免费| 亚洲男人天堂手机在线| 国产一区视频在线| 久久久久久中文字幕| 亚洲精品一区av在线播放| xvideos亚洲人网站| 精品久久久久久国产91| 久久久久久亚洲| 国产精品扒开腿做爽爽爽男男| 欧美国产日韩免费| 欧美另类精品xxxx孕妇| 国产精品久久久久久久一区探花| 久久亚洲一区二区三区四区五区高| 成人欧美一区二区三区在线| 精品国产乱码久久久久酒店| 欧美黑人一级爽快片淫片高清| 欧美大片免费观看在线观看网站推荐| 日韩电影中文字幕在线观看| 欧美亚洲另类激情另类| 日韩精品视频免费在线观看| 九九九热精品免费视频观看网站| 69av视频在线播放| 在线看日韩欧美| 正在播放欧美一区| 美日韩精品视频免费看| 性欧美xxxx视频在线观看| 欧美在线视频播放| 欧美成人精品一区二区| 久久综合久中文字幕青草| 亚洲人在线视频| 久久露脸国产精品| 国产美女精品视频免费观看| 精品日本高清在线播放| 国产精品中文字幕在线| 久久亚洲精品毛片| 亚洲欧美精品伊人久久| 久久成人免费视频| 国产91色在线免费| 日韩亚洲欧美中文高清在线|