写完题目才发现好像有些标题党...
背景
事情是这样的,之前经常上饭否看一些大佬们的脑洞以及开一些新脑洞,但久而久之,不知道是自己手残还是被机器人操作了,关注列表出现了一大批自己不认识的陌生人,突然递增到了140+人
过多的人数已经严重打扰了我的timeline,只能手动取消关注。在取消关注的时候才发现,饭否只支持单个人取消关注,没办法批量操作。
难道只能连续点140下吗...得考虑下如何进行批量操作。
思路
批量操作,一般是由脚本来完成,这里我们先观察一下饭否的取消关注方式:
- 每次点击取消关注后,会发送一个POST请求,看一下data中的主要内容:
- 其中用户信息和鉴权验证,都是放在请求的cookie中实现的。
- 在data信息中,有如下几个字段。由分析可得知,其实重要信息就是friend好友id的获取:
- action: friend.remove,是处理接触好友的方法名(固定)
- friend: 好友的id
- token: 本人的token值(固定)
- ajax: 是否为ajax方式(固定)
- 那么我们看一下html部分,经测试发现,每个人是一个li标签,子元素a标签的href取值,即是每个人的id
- 所有关键信息都可以获取到了,下面便可以写脚本了。
实现
这里有两种方式:
- 一种方式是利用node和shell脚本,通过ajax对好友关系进行遍历,拿到html后获取到所有人的id,之后伪造remove请求,对idList中每个元素进行取关处理。
- 直接在console中处理,获取到DOM元素之后过滤到idList列表,之后对每个id进行remove请求的fetch操作。
这两种方法相比,第一种方法需要处理用户鉴权、登录信息,以及引用ajax依赖等,考虑到时间成本,直接使用第二种方法进行实现:
- 手动进入某个页码,遍历DOM中的每个
<li>
标签,获取到所有的href
取值。 - 先取关一个好友,然后在network中copy请求的fetch操作,这样的话可以直接设置header,利用cookie攻击
- 处理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"});
})
尾巴
这种方式虽然简单,但仍需要手动的进行分页的控制,大家有兴趣可以试试第一种实现方式来做脚本测试一下。