预计阅读时间: 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关注公众号回复‘极客部落’获取源代码