有人知道前海好吗这个网红叫什么吗?

零基础写Java知乎爬虫之抓取知乎答案
投稿:hebedich
字体:[ ] 类型:转载 时间:
上篇文章我们已经能把知乎的问题抓出来了,但是答案还木有抓出来。这一回合,我们就连着把答案也一起从网站中抠出来=。=
前期我们抓取标题是在该链接下:
/explore/recommendations
但是显然这个页面是无法获取答案的。
一个完整问题的页面应该是这样的链接:
/question/
仔细一看,啊哈我们的封装类还需要进一步包装下,至少需要个questionDescription来存储问题描述:
import java.util.ArrayLpublic class Zhihu {&public S// 问题&public String questionD// 问题描述&public String zhihuU// 网页链接&public ArrayList&String&// 存储所有回答的数组&// 构造方法初始化数据&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 = pile("&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();&&}&&&}
接下来,就是在Zhihu的构造方法里面,通过url获取所有的详细数据。
我们先要对url进行一个处理,因为有的针对回答的,它的url是:
/question//answer/
有的针对问题的,它的url是:
/question/
那么我们显然需要的是第二种,所以需要用正则把第一种链接裁切成第二种,这个在Zhihu中写个函数即可。
// 处理url&boolean getRealUrl(String url) {&&// 将&&// 转化成&&// 否则不变&&Pattern pattern = pile("question/(.*?)/");&&Matcher matcher = pattern.matcher(url);&&if (matcher.find()) {&&&zhihuUrl = "" + matcher.group(1);&&} else {&&&&&}&&&}
接下来就是各个部分的获取工作了。
先看下标题:
正则把握住那个class即可,正则语句可以写成:zm-editable-content\"&(.+?)&
运行下看看结果:
哎哟不错哦。
接下来抓取问题描述:
啊哈一样的原理,抓住class,因为它应该是这个的唯一标识。
验证方法:右击查看页面源代码,ctrl+F看看页面中有没有其他的这个字符串。
后来经过验证,还真出了问题:
标题和描述内容前面的class是一样的。
那只能通过修改正则的方式来重新抓取:
// 匹配标题&&&pattern = pile("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.ArrayLimport java.util.regex.Mimport java.util.regex.Ppublic class Zhihu {&public S// 问题&public String questionD// 问题描述&public String zhihuU// 网页链接&public ArrayList&String&// 存储所有回答的数组&// 构造方法初始化数据&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);&&&P&&&M&&&// 匹配标题&&&pattern = pile("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 = pile("/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() {&&&}&// 处理url&boolean getRealUrl(String url) {&&// 将&&// 转化成&&// 否则不变&&Pattern pattern = pile("question/(.*?)/");&&Matcher matcher = pattern.matcher(url);&&if (matcher.find()) {&&&zhihuUrl = "" + matcher.group(1);&&} else {&&&&&}&&&}&@Override&public String toString() {&&return "问题:" + question + "\n" + "描述:" + questionDescription + "\n"&&&&+ "链接:" + zhihuUrl + "\n回答:" + answers.size() + "\n";&}}
Spider.java
import java.io.BufferedRimport java.io.InputStreamRimport java.net.URL;import java.net.URLCimport java.util.ArrayLimport java.util.regex.Mimport java.util.regex.Ppublic class Spider {&static String SendGet(String url) {&&// 定义一个字符串用来存储网页内容&&String result = "";&&// 定义一个缓冲字符输入流&&BufferedReader in =&&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"));&&&// 用来临时存储抓取到的每一行的数据&&&S&&&while ((line = in.readLine()) != null) {&&&&// 遍历抓取到的每一行并将其存储到result里面&&&&result +=&&&}&&} catch (Exception e) {&&&System.out.println("发送GET请求出现异常!" + e);&&&e.printStackTrace();&&}&&// 使用finally来关闭输入流&&finally {&&&try {&&&&if (in != null) {&&&&&in.close();&&&&}&&&} catch (Exception e2) {&&&&e2.printStackTrace();&&&}&&}&&&}&// 获取所有的编辑推荐的知乎内容&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();&&}&&&}}
import java.util.ArrayLpublic 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);&}}
以上就是抓取知乎答案的全部记录,非常的详尽,有需要的朋友可以参考下
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具想写一个爬虫程序,用什么框架比较好 - ITeye问答
RT 想用java写个爬虫 主要想爬取微博的数据 求指教
采纳的答案
1、页面请求使用httpclient比较好,如果涉及多线程最好使用4.x版本
2、页面解析,推荐使用jsoup,功能比较强大
另外,针对网络爬虫上面两点是基本的,但是微博数据是需要登录才能获取的,所以需要考虑模拟登录
这个基本上只能自己做的玩玩,大规模的访问任何微博应该都有ip或者次数限制的,用httpclient+htmlparser就ok了
apache natch
用httppaser好像有这方面的功能吧
已解决问题
未解决问题在写一个爬虫代理服务,有人需要吗? - V2EX
在写一个爬虫代理服务,有人需要吗?
172 天前 &sivacohan
因为之前写了一些小爬虫,管理代理池一直是一个很麻烦的事情。所以就写了一个小东西。来帮助自己管理代理池,自动更换出口代理 IP 。
目前已经实现的功能有:
1 、标准的 HTTP 代理 Basic Auth
2 、利用 HTTP header 来区分进程,即一台服务器上有多个 fetcher 进程将分配多个出口 IP
3 、对于同一个进程,按照不同的请求域名进行分流,即一个 fetcher 也有可能会分得多个 IP
4 、状态监控,对于返回 403 , 500 的请求直接更换出口 IP
5 、简单的,基于正则的结果验证,用户可以检测“请输入验证码”,“稍后再试等情况”
6 、目前支持 GET, POST, PUT, DELETE 方法
正在准备支持的功能:
1 、增加 Web 管理界面
2 、增加 HTTPS 支持,目前不支持 connect 方法
3 、为部分网站增加缓存
简单来说,这就是一个代理服务,与常规代理不同的是,我可以为一台机器分配更多的出口,极限情况为:一台机器的 fetcher 进程数 n ,抓取的网站数量 m ,出口数量 p = n*m
有人对这个东西有兴趣吗?如果做成一个平台,你希望得到什么样的服务,以及你愿意为这个服务支付多少费用呢?
1271 次点击所在节点 &
pango172 天前其他都是空的。
关键是:你们有多少个 ip ?都分布在哪些国家?都是干净的吗?
laoyuan172 天前接口可以简单点,两个参数验证身份,一个目标 URL ,一个方法,一个 POST 的 raw data 。
费用可以设几个档,我大概一个月几千万请求,不到一个 T 流量,可能用到几十上百个 IP ,一月 100 块钱肯定出的起。
gimp172 天前@ 这个需求, 100 软妹币太少太少了。
laurent172 天前我最近也写了个类似的东西,实际使用下来,发现最关键的还是代理 IP 的质量。代理 IP 质量不好的话,爬虫大多数时间都卡在等待可用 IP 上了。所以觉得这个服务的最大价值在于代理 IP ,那么定价自然是参考其他的代理 IP 提供商咯。
sivacohan172 天前@ 目前正在计划,主要就面向国内用户了。当前自己用了 20 多个 IP ,主要是阿里云和百度云的。如果有人需要的话,就再买些 IP 咯。网上的免费 IP 只能当玩具用。
@ 不知道你爬去的是什么网站。我流量和你差不多,总共才用了 10 个 IP 。
@ 终于有人给了一个中肯的评价了。他那个需求,自建的成本怎么也得 3k 到 4k 。
@ 我现在是想找些人自建 IP 池,免费 IP + 各种云的 IP + 少量 ADSL 小区宽带。而实际上,我这个不太好定价。代理服务商是多少钱多少 IP ,封了就没了。我是根据爬去情况动态更换的。有人捣乱我这边会跪的很惨的……
herozzm171 天前关心 IP 池怎么来的
imn1171 天前同 1 楼,我想爬北都集团, 2333
fchypzero171 天前對這套感興趣,畢竟手上有很多 ADSL 寬帶
gimp171 天前
挺正规的爬虫代理服务商,价格供参考。
scnace171 天前好巧 我最近也在写
我连 ip 池都是免费的代理那里抓来的 233 大概有 7w 个 还没测 不知道能用的有多少。。。
daiv41 天前楼主做出来了吗?
我想要稳定一些的代理 IP 。
例如一个 IP 用一个星期
sivacohan41 天前@
做完自己用了,只做 IP 池管理。
你的需求可以考虑用 bae 的 Python worker 版,单个 IP 一个月大概才 4 块钱。
daiv41 天前@ 这么好? 我去试试。 除了 IP 费用,其他无费用了?
sivacohan41 天前@ bae ,提供一个 Python worker 环境。选最低内存最便宜那个。
在上面部署一个 tornado 的代理。
然后你需要申请一个端口转发,每月好像一块钱吧。
很简单,看一下就明白了。这是市面上能直接买到的最便宜的 IP 了。
hadoop19 天前@ 赞啊,这思路不错。如果 bae 能自动开,就更好了。带宽被限制了吧?
sivacohan19 天前@
没法自动开,接口都跪了。
单个用户限制 100 个 bae 实例。
而且量大的话,可能会有几个 bae 分到一个 ip 的情况。
玩玩可以,实际的话,成本肯定更高。
第 1 页 / 共 1 页&
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到
上打开本讨论主题的完整版本。
是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
is a community of developers, designers and creative people.(183****7403)
(AlbertLee)
第三方登录:

我要回帖

更多关于 很少有人知道的网站 的文章

 

随机推荐