我不想关注你了,饭否

2,212 阅读2分钟

写完题目才发现好像有些标题党...

背景

事情是这样的,之前经常上饭否看一些大佬们的脑洞以及开一些新脑洞,但久而久之,不知道是自己手残还是被机器人操作了,关注列表出现了一大批自己不认识的陌生人,突然递增到了140+人

人数

过多的人数已经严重打扰了我的timeline,只能手动取消关注。在取消关注的时候才发现,饭否只支持单个人取消关注,没办法批量操作。

取消关注

难道只能连续点140下吗...得考虑下如何进行批量操作。

思路

批量操作,一般是由脚本来完成,这里我们先观察一下饭否的取消关注方式:

  1. 每次点击取消关注后,会发送一个POST请求,看一下data中的主要内容:
    POST请求
  2. 其中用户信息和鉴权验证,都是放在请求的cookie中实现的。
  3. 在data信息中,有如下几个字段。由分析可得知,其实重要信息就是friend好友id的获取:
    • action: friend.remove,是处理接触好友的方法名(固定)
    • friend: 好友的id
    • token: 本人的token值(固定)
    • ajax: 是否为ajax方式(固定)
  4. 那么我们看一下html部分,经测试发现,每个人是一个li标签,子元素a标签的href取值,即是每个人的id
    dom元素
  5. 所有关键信息都可以获取到了,下面便可以写脚本了。

实现

这里有两种方式:

  1. 一种方式是利用node和shell脚本,通过ajax对好友关系进行遍历,拿到html后获取到所有人的id,之后伪造remove请求,对idList中每个元素进行取关处理。
  2. 直接在console中处理,获取到DOM元素之后过滤到idList列表,之后对每个id进行remove请求的fetch操作。

这两种方法相比,第一种方法需要处理用户鉴权、登录信息,以及引用ajax依赖等,考虑到时间成本,直接使用第二种方法进行实现:

  1. 手动进入某个页码,遍历DOM中的每个<li>标签,获取到所有的href取值。
  2. 先取关一个好友,然后在network中copy请求的fetch操作,这样的话可以直接设置header,利用cookie攻击
    copy as fetch
  3. 处理idList中的元素,对每个元素根据步骤2中的fetch,替换body中的内容进行处理。

下面贴出具体代码:

// 获取idList
let nameList = [].map.call(document.getElementsByClassName('avatar'),(item)=>item.href.replace('http://fanfou.com/',''))

// 进行fetch操作
nameList.forEach(item=>{
	fetch("${url}", {"credentials":"include","headers":${header信息},"body":`action=friend.remove&friend=${item}&token=xxx&ajax=yes`,"method":"POST","mode":"cors"});
})

尾巴

这种方式虽然简单,但仍需要手动的进行分页的控制,大家有兴趣可以试试第一种实现方式来做脚本测试一下。