万网皆可爬-爬虫实战系列之-极客时间部落沦陷

211 阅读4分钟
原文链接: mp.weixin.qq.com

预计阅读时间:  3.6分钟

事情来源

在家闲来无事,想学习下大牛们的心得,于是打开极客时间 app准备安心学习,突然映入眼帘一则广告炫“装备”大赛#开始啦 简单撸了一眼,咱也不是爱凑热闹的人(咱也不差这点钱~),于是打开课程开始学习。

这一学不要紧,学习的太过投入到了吃饭的时间,吃饭前肯定要刷会手机啊,进去极客时间部落去看个热闹,这一看可来了兴致,小编发的一张图很有意思,作为一个技术流是时候展现真正的技术了。

咱就按小编说的干,抢个点赞第一!!!说干就干!!!

本来想用抓包工具分析app接口的,还好多思考了下,极客时间有网页版,网页有部落功能吗?

打开网页,登录果真有!这下省事了,不用抓包app了,直接chrome F12就能搞定了,天助我也!!!

查看robots协议

User-agent: *Disallow: /data/Disallow: /plus/Disallow: /content/Disallow: /*.php$Disallow: /*.asp$Sitemap: https://time.geekbang.org/sitemap.txt

作为一个小爬虫还是有必要关心下这些常识的,看着可以干!就这么搞了!

分析接口流程

帖子列表

  • 浏览器打开开发者模式,F12进入

  • 根据小编提示进入我是数码控 活动页面

  • 选择network 下的xhr 选项,这里列出了所有的ajax请求接口

极客时间的接口定义还是比较清楚的,根据接口见名知意 的原则初步定位https://horde.geekbang.org/serv/v1/channel/posts 这个接口是帖子列表接口 复制此接口的response信息到json编辑器观察下结果(我用的是notepad++的jstool插件),结果太多只截取关键部分。

从图中可以分析出关键信息字段,没错这就是我们要的接口。往下滑动会发现分页也是请求的这个接口,进一步确认了我们定位的信息。 从分页请求观察请求参数可以发现参数比较简单,下一页请求index 信息来源于上一页的结果

点赞列表

观察点赞列表可以发现当点赞人数超过20个,会出现等点燃了动态字样 ,不经意鼠标一点击分页显示了点赞人员,观察xhr 请求会发现请求的接口路径是https://horde.geekbang.org/serv/v1/likes/list ,参数和结果分析同动态列表不在赘述。

这里有个强调的地方index 参数来源于上一页请求结构返回的current+1 。为什么接口不统一?

顺带点赞操作

点击小火苗按钮观察请求接口https://horde.geekbang.org/serv/v1/likes/add

  • 分析到这里我们需要的接口足够了

  • 接下来开始写代码

编码

认证怎么做?

关于认证的详情这里不做赘述,只说明本次使用cookie进行认证。

难道还要研究登录接口吗?NO!!!我们就是一锤子买卖没必要做那么复杂,直接复制request header的cookie信息。

亮出大杀器

maven 依赖

<dependency>  <groupId>org.apache.httpcomponents</groupId>  <artifactId>httpclient</artifactId>  <version>4.5.11</version></dependency>

分析接口的时候我们发现三个接口使用的数据提交方式是一致的,统一使用的 post json 的形式,可以简单封装一个方法进行数据请求。

关键代码

public String sendJsonPost(String uri, Map<String, Object> param) {  String html = "";  HttpPost post = new HttpPost(uri);  addHeader(post);  String paramJson = JSON.toJSONString(param);  StringEntity requestEntity = new StringEntity(paramJson, "utf-8");  requestEntity.setContentEncoding("UTF-8");  post.setHeader("Content-type", "application/json");  post.setEntity(requestEntity);  CloseableHttpClient client = getHttpClient();  CloseableHttpResponse httpResponse = null;  try {    httpResponse = client.execute(post);    HttpEntity entity = httpResponse.getEntity();    html = EntityUtils.toString(entity);    System.out.println(html);  } catch (IOException e) {    e.printStackTrace();  } finally {    try {      // 很重要      httpResponse.close();    } catch (IOException e) {      e.printStackTrace();    }  }  return html;}

  • addHeader 方法添加request信息,直接从浏览器复制下来的信息

  • getHttpClient 封装的工具类

  • httpResponse.close(); 这一句很重要,很多人是不写的,在运行次数很少的情况下是不会出问题的,如果一直循环运行不关闭的话会出现报错导致程序停止

最终结果分析

点赞最多的:https://horde.geekbang.org/message/detail/wJ9QkPN5TmBfv7eu7uM1WnyNskdy6BBkU4V_KABvXRw?tab=0

总共发布话题221次总共点赞8474次点赞最多的次数95次,第二名69 点赞最少的12次 点赞前三的次数221,220,219(5个)点赞前三的用户Alex,BIZGO-WX😊ི,(Aspirin,miion,ran,Leeby,Geek_a46f6a)

统计sql

SELECT * FROM horde.post ORDER BY post.like_count DESC;SELECT SUM(p.like_count) FROM horde.post p;SELECT COUNT(*) c,post_like_user.post_id FROM horde.post_like_user  GROUP BY post_like_user.post_id ORDER BY c DESC;SELECT COUNT(*) c,post_like_user.user_id FROM horde.post_like_user GROUP BY post_like_user.user_id  ORDER BY c DESC;

小小的遗憾

  • 虽然写了脚本但是没有一直运行,不然也得拿个点赞最多啊,下次再有活动一定一直运行~

  • 极客时间点赞列表里面没有返回点赞的时间,有时间字段的话可以分析下点赞频率看下是机器人还是手动点赞,我觉得后台肯定是有存储的

PS:10点就关机睡觉了~

自己的点赞数据 210 排名12关注公众号回复‘极客部落’获取源代码