首页 > Java > java教程 > 正文

零基础写Java知乎爬虫之抓取知乎答案

黄舟
发布: 2016-12-24 11:41:34
原创
1652人浏览过

前期我们抓取标题是在该链接下:

http://www.zhihu.com/explore/recommendations

但是显然这个页面是无法获取答案的。

一个完整问题的页面应该是这样的链接:

http://www.zhihu.com/question/22355264

立即学习Java免费学习笔记(深入)”;

仔细一看,啊哈我们的封装类还需要进一步包装下,至少需要个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;
 }
登录后复制

接下来就是各个部分的获取工作了。

先看下标题:

234.jpg

正则把握住那个class即可,正则语句可以写成:zm-editable-content\">(.+?)<

运行下看看结果:

235.jpg

360智图
360智图

AI驱动的图片版权查询平台

360智图 143
查看详情 360智图

哎哟不错哦。

接下来抓取问题描述:

236.jpg

啊哈一样的原理,抓住class,因为它应该是这个的唯一标识。

验证方法:右击查看页面源代码,ctrl+F看看页面中有没有其他的这个字符串。

后来经过验证,还真出了问题:

237.jpg

标题和描述内容前面的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);
   }
登录后复制

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

238.jpg

初步暂定正则语句:/answer/content.+?<div.+?>(.*?)</div>

改下代码之后我们会发现软件运行的速度明显变慢了,因为他需要访问每个网页并且把上面的内容抓下来。

比如说编辑推荐有20个问题,那么就需要访问网页20次,速度也就慢下来了。

试验一下,看上去效果不错:

239.jpg

OK,那就先这样好了~下次继续进行一些细节的调整,比如多线程,IO流写入本地等等。

 以上就是零基础写Java知乎爬虫之抓取知乎答案的内容,更多相关内容请关注PHP中文网(www.php.cn)!

相关标签:
知乎
知乎

知乎app是广大用户朋友们常用的问答工具,集搜索、问答、社交等服务功能为一体,超多内容随你阅读观看,让你发现更多精彩。有需要的小伙伴快来保存下载体验吧!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号