为啥要关注N多大V
今天突然意识到一个问题,在知乎上,我通常只关注那些价值观我比较认同的人,还会在发现关注的人的回答和我的价值观不一致时取消关注。
可是这么一来,我的世界会越来越小,我固有的偏见也就会越来越深,还怎么发现更大的世界呢。
关注更多的人,就能从更多的角度观察这个世界。但是尽管噪声也是声音,比较价值要小一些,所以选择关注下大V。
怎么找大V
根据知乎上有些回答的建议,先找个大V,然后从TA的关注列表里面加关注。
我对于大V的认定目前比较简单,看TA的回答赞同数是不是比较高。
方法基本确定了,但是在页面上一个个点关注,有点慢啊....
怎么自动化加关注
于是,我写了个脚本(比较长,代码留在最后了)。
在调试的过程中,估计是一开始没有考虑发送一大波请求会产生问题,导致....知乎把我封号了!在通过发送短信解除封号后,我在代码里面加入了延迟,尽量模拟人的操作方式吧。
代码使用方式
简单用法
- 打开一个大V的个人页面,例如:https://www.zhihu.com/people/excited-vczh
- 通过 F12 打开浏览器控制台
- 将代码粘贴进去,回车
- 等待 .... DONE!
注:2015/12/29 更新 - 简化自动关注步骤
高级用法
请参考代码注释....
附录
声明
代码有风险,粘贴需谨慎!
代码
(function (factory) {
  var zhv = factory(window.$)
  // 1. 自动关注所有大V
  zhv.autoFollowBigVers()
  // 2. 手动处理,自行判断大V
  /*
  zhv.getAllFolloweesOfCurrentUser(function (userList) {
    // user 数据结构参考下面的说明 <UserObject 用户信息数据结构>
    zhv.followUsers(userList.filter(function (user) {
      return user.agreeCount > 1000
    }))
  })
  */
  /*
   * UserObject 用户信息数据结构
   *
   * - {string} id: hash_id
   * - {string} name: 该用户名称
   * - {boolean} hasFollowed: 该用户是否已被你关注
   * - {number} followerCount: 该用户的关注者数目
   * - {number} askCount: 该用户的提问数
   * - {number} answerCount: 该用户的答题数目
   * - {number} agreeCount: 该用户获得的赞同数
   */
})(function ($) {
var zh_xsrf = $('input[name="_xsrf"]').val()
var zh_followee_collection = []
var exports = {}
exports.autoFollowBigVers = function () {
  getAllFolloweesOfCurrentUser(function (userList) {
    followUsers(userList.filter(isNotFollowedBigVer))
  })
}
exports.getAllFolloweesOfCurrentUser = getAllFolloweesOfCurrentUser
exports.followUsers = followUsers
/*
 * @param {function} [done] - 执行完毕后调用的回调函数,callback({UserObject[]})
 */
function getAllFolloweesOfCurrentUser(done) {
  var currentUser = getCurrentUserInfo()
  var hash_id = currentUser.id
  var followeeCount = currentUser.followeeCount
  // 清空已缓存的用户
  zh_followee_collection.length = 0
  var i = 0
  var loadCount = Math.ceil(followeeCount / 20)
  var timer = setInterval(function () {
    if (i < loadCount) {
      getFolloweeList(hash_id, 20 * i).done(function (data) {
        if (data.r === 0) {
          data.msg.forEach(function (item) {
            var user = parseUserInfoFromHTML(item)
            zh_followee_collection.push(user)
          })
        }
      })
      console.log(i + '/' + loadCount + ' ' + ((i * 100 / loadCount).toFixed(2) + '%'))
      i++
    } else {
      clearInterval(timer)
      console.log('加载当前用户所有关注的人,完毕')
      if (typeof done === 'function') {
        done(zh_followee_collection)
      }
    }
  }, 200)
  console.log('尝试加载当前用户所有关注的人,共' + followeeCount + '人')
}
function parseUserInfoFromHTML(html) {
  var $el = $(html)
  var $btnFollow = $el.find('.zm-rich-follow-btn')
  var hash_id = $btnFollow.attr('data-id')
  var hasFollowed = $btnFollow.hasClass('zg-btn-unfollow')
  var userName = $el.find('.zm-item-link-avatar').attr('title')
  var $links = $el.find('.details').find('a')
  var followerCount = parseInt($links.eq(0).text(), 10)
  var askCount = parseInt($links.eq(1).text(), 10)
  var answerCount = parseInt($links.eq(2).text(), 10)
  var agreeCount = parseInt($links.eq(3).text(), 10)
  return {
    id: hash_id,
    name: userName,
    hasFollowed: hasFollowed,
    followerCount: followerCount,
    askCount: askCount,
    answerCount: answerCount,
    agreeCount: agreeCount
  }
}
function isNotFollowedBigVer(user) {
  if (user.hasFollowed) {
    return false
  } else {
    // 各种主观的评价大V的标准
    if (user.agreeCount > 1000 && user.followerCount > 500) {
      return true
    } else if (user.agreeCount > 100 && user.followerCount > 2000) {
      return true
    } else {
      return false
    }
  }
}
/*
 * @param {UserObject[]} userList
 */
function followUsers(userList) {
  var total = userList.length
  if (total > 0) {
    console.log('关注' + total + '个用户,开始....')
    userList.forEach(function (user, i) {
      setTimeout(function () {
        console.log(
          (i + 1) + '/' + total + ' ' +
          user.name + ' ' +
          user.agreeCount + '赞同 ' +
          user.followerCount + '关注'
        )
        followUser(user.id)
        user.hasFollowed = true
        if (i + 1 === total) {
          console.log('结束')
        }
      }, i * 200)
    })
  } else {
    console.log('没有要关注的用户')
  }
}
/*
 * @return {UserObject} 当前用户信息
 */
function getCurrentUserInfo() {
  var $btnFollow = $('.zm-profile-header-op-btns').find('.zm-rich-follow-btn')
  var $followNums = $('.zm-profile-side-following').find('strong')
  var $userNums = $('.profile-navbar').find('.num')
  return {
    // 用户的关注按钮上有该用户对应的 hash_id
    id: $btnFollow.attr('data-id'),
    name: $('.title-section').find('.name').text(),
    // TA关注的人数
    followeeCount: parseInt($followNums.eq(0).text(), 10),
    // 关注TA的人数
    followerCount: parseInt($followNums.eq(1).text(), 10),
    answerCount: parseInt($userNums.eq(1).text(), 10),
    agreeCount: parseInt($('.zm-profile-header-user-agree').find('strong').text(), 10)
  }
}
function getFolloweeList(hash_id, offset) {
  return $.ajax({
    type: 'POST',
    url: '/node/ProfileFolloweesListV2',
    data: {
      method: 'next',
      params: JSON.stringify({
        "offset": offset,
        "order_by": "created",
        "hash_id": hash_id
      }),
      _xsrf: zh_xsrf
    },
    dataType: 'json'
  })
}
function followUser(hash_id) {
  return $.ajax({
    type: 'POST',
    url: '/node/MemberFollowBaseV2',
    data: {
      method: 'follow_member',
      params: JSON.stringify({"hash_id": hash_id}),
      _xsrf: zh_xsrf
    },
    dataType: 'JSON'
  })
}
return exports
})