// ==UserScript==
// @name 你果然关注了这些人(微博特征用户关注检测)
// @namespace http://tampermonkey.net/
// @version 0.5
// @description 新浪微博,查看用户关注「典型」用户的数量。一个常见的应用场景就是看ta关注了哪些你会拉黑的人。
// @author evalcony
// @homepageURL https://github.com/evalcony/weibo_feature_user_maching
// @match https://weibo.com/*
// @match https://m.weibo.cn/*
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPkAAADKCAMAAABQfxahAAAA81BMVEX////mFi0AAAD/mTPkAADlAB3mEyvlABTlACP/mDDlABnlABflACDmDynkAAj/ly3/kx7/lSb/kRX98vPkAAf4ztH0rbL/9e362tz74eP+9/jzpav1uLzwipHy8vL/6NbsZ3HpRFLAwMD3w8fudn/xk5r86+z2wMT/07H/8eb/59T/4cr/x5roM0TynaPvfoagoKCSkpL/oET/qFn/von/28D/r2jrV2P/yqD/tnjpPEvnKj3tbnjvgopZWVmzs7PX19cpKSnqTVqsrKw5OTni4uKCgoJRUVE1NTVpaWlmZmYSEhL/tHT/qVz/o013d3cfHx+isyIqAAARFklEQVR4nN1daVviyBaWNhshCRBWWZRdbRWXVlHAbsceu6c3+/7/X3MTcCGp7ZxKAer7PDMfZoTkpU6d/VRtbLwhVHYurs6vLx/ONgOcnX36fX64d7C/7rdaNj4eXmb9XC6fz2bTmzOk09lsPp/zc2fne++X/sWZn39iTCAd0M//3qus+yWXgWufxfoZ2Zz/cPXuyP/OiXg/rr3/52Ld76oUez6I+Hzlc4fvaOFhK/6EvH/9XvTdFY55sPDvhfunLJJ5yP183W+tAnk08QD53N663zs5sML+iNzDmxd5SeaByF+t+9UTYlPoxTCX/dPbtnDXUht9vuy5g3W/fRJ8hDsyBNL+4bpfPwkkzNoLcr/X/foJUBHHKxzkH9b9/gmw4ydZ9ezmG9Zz+2e5Ofd0Np/L+b4/+1eYqGAG7YvUs2+Y+sbFn4Con3u4vrrY2Z8Tqewf7B1ebvq5vIj926YeLPwO1SmrXJxv+gLyb506G/uHm3xVkN1c9ysuDx+vfZ7Hk33LGl6EyjmPe/5y3e+3TNTOOTKfe9PenBD7l2yvx39f2UkCF3mmyOfeq4J/wiUrwlm5litUu+VhgHK3WlvJA/dYEp9bXXau0O2PLM8zbT2AbXreuF9dwWN3sgxF5++s4OkbG6X+kWc6lpFagKsXjxrLf3TljL7Z02fLf3bp2PIcN0WBa05WsO6f6NRzS07NbTVdM7rWUe5af7nPD/GHTt1fpn5vtDWHTXsGb5rsEZUAor+hr3p2aSma2tAyqUIehdmT/P4gMvuT9ec4+33FSzA+UNXckpRc4cazBcv9iGJZ5vsrv/2FZESYpvA/MTsGKmmacct+SsCPhcKx54Boz6gP8A/YyZESnM37lx/pf75PdWl85YnoWhPBO5WyWugn7DM8lKz/QGdDLbwrX/ShqSN4B9C2sI+gb9w590uqzFOLFGp3esMF7u8XODfIZxzwKg5Zn1o7pW31rMJIfavtYXmnUoaDfMo1P/WcoxGi1mfU2fQbzULzDuCVcI85E6RY87S8Ok3e84pyFF0XucGfoA9xDxKm1rM5cgdXKDXodFoF71qriBf0ObDaXbTmYf2QpH5FWXQVFdaGLSXoM7hHuGddiktM6RyZkqek4rPXSXnXRhKa7RlYFbcHaJ6gCDKttSqfkHjJkV/wEEXk80A1NNJPoTBPKO7HWoIFD6EVcA/kGvRnUoTiPiR3ej5JWmpwZCfjHaw5kjk7wbYIP77VKe57OkGxqeEBYlHRmqMTkjths3c2rCQHYFQRyQwrpeeC+HnA6CWV9BCexIMPzi//XF8dfNw5uDh/oJdQc/GKAkU1yvYJFsaJJT0l4b4SqBzSygqEKFdIcZfc6KUERnwB7iQp8wDnlK1PLOgfQtzlkrB1FZIewBopYE7LrRO0KH6cL/GonqeEt0SYSkfljKAed2J3SHGXCNLvVGzxGWypVByFOhGEE7uYXHNCDYowmCjZ4jOYyCiVCcJgp7OxvyA3eh5Zcqjaya34M4TmvFAtNcr14bBebpS2eH9MuOZxWSbduCxOuXcV6bYZ3DH7QVuNfmuie6aZscNipJ0xPXMyLTMzd/F26PiKXhAWHZeSKqsknnKa1IfUuv073cvolht7mGvZ2mRId3jjvkq8krJD+jIYszbUFPIOtnmXfESp39ZMnV2Sc3WtR83Tx5jFnRmKL4Pw3JuqrNkjtPgDdqe6pwv1iKPRkljx7GTcXFMiVTDxnqmWeMyP2W1pvPLrIsw2qe3i4h6PSCjZZyjxqWLiKbv+8uWlnmkirKVlEBIf38i5WMGJksMDEm9lFBN/2eaDfsoDrvYTXDeu6OIbOZ50eZBlrp74U8652yqK9zYBi7CIS2LeUuaxLsBuNuo9CyPlC8jETeJymC9hxUM4GRsp5QvQolt9OdI+XQ7xZHCiTReEhou5r1IaTrU5UwQzYtr2Yo55vGhIKVIIiTdfJ/FUJtJWF6+/5GIsJHy4YXHdFBmwIu1Vce815pXT+kYExMtqfXWFcFMcZvHC2UfCe00Lun+7r5Z4dKPHmcdzkGTeWdAXV5WuEK8A3kK0Hjdqcbf9nMhM8NPOAwnvanUwF7tno6kJIuNOmvM8t9Qwec3Eo2m8aLqJSLJRiiy8auqdumTjMhBZ8wi3dLw8Tio4bmGttwxnXSG8SFZuscJMdDlS6shxg7+AuuIUjHJ40Uj14mlgK0vOKJG+K6cRsvSK7dkMhhV74/2wGzif838TvWG0iiKzMayAbmlcNShJ68rF3t4FpSeOzDlzFNz4dWu3AM4xU17joBUUWW2Qr127pVBVOUqFheW7Nl77Jk+hWqXjISy7qjZI0uW2IkQCFgFIc86qIR+9at9tDlTxPb7mrNaoG5Wb3HAty9F1286EsG3dcSw3XjKTAKoEHd/ojP4gNZbccJ1wGtNMtVu95qwQHKJcH/aPW3cTO5zYdOTzj6Q15yNaYskyqokJ3mcO17JNTb+7qXerzFa/wlap3Bw53PIhD4xCLAs7i31EaYbP3sKM4ZCsHVOb9OolYHdjoTRsucUMnn0ROQSz89I+ls/SiSfIwgSsi+N+F9vSuTEoTw1AETXyKGSD+EZ4ZGwuH3ZPss5JrMnKuqt7qeOu9Hx5dTjGVJmQwj5DZe/88vKcOdfXk5L1gPbRED2EFcNgOPZE86xPwA6CiCGj1w3HmySmPcdWU4cMtUqN+QmAzz+5pn2jcpy8MS5CgiWvLv4qDIbYCpqltZWfIFBtQYbAzHEZrUrZKCDTMI7WWsrpAVsQ7q7ttesSU71UTFFBueMdq3owga1REbDvAvIjJSJXxag3p3ijUNpIlCagnWeZVj/5e7Th6s3SekvlHWIIm/k0dC2p7HXBu9z17tRYMT4GbWAB29FuEh3RA47K9dSuKnICDDXgOzlmAivXAP7AribhOcqimgL6lIZ5JG1mgEtur+IYnAWMoC6G9CE1u6Bdbqxywee4AaufTFtK644hS245qsYQEKiDja1lS8hjCfLLZu5Wc8pZDPAcuKHhHZsRwHYWsbNG27edrycnp6enJ187t9vod3oGIv2vYXX8QPzdhoYZNdrunH7+9SGCX59Pb5Gv9QREnxKWelNoPFxEmvf+5PsHBj5/kVr7ITyWQgq8LsqFuDbYa/v6L4v2HD9usbwDTOGneGgYLSz0YlwH6Brf/+XTnuG/Dp46vO5jmAjjJtJvrgUjfv8ZwDvEv7dY5gMTnBq12uBvLQgUCFDUtyHr/YS/WOpl+FY3wfnJMr+QZnggB+EEwTvELZI6xPA+woOGrYL2L40yWEbgXqDXKDjFMR/Ae4+hqVlB+g0kO1/RvAP8xFFvIvQ7zI1tcMMhpwX4ih8yxANFh2JeQyg52FA/N/EI6k3AS7oU9T5i0UE7nVvHB8jN9i8xRRY+Y5jX4E6sDgnWt3jb3BbH49vyvAN8w1CHp8VBosqzaYDjP5IR//AB48+V4DM1kAJ7j/NDFsU+cAJRnwMTwsAbbGxAzMapIgJUpLRyewZmqx+Di9wAk17jSJC42w7jsLKAkPddsLgb4o3OUXDi362jgPiHf+DMETVP8XFcu2w/RmjRkmq3RyAWHV7g94TyWme6B64w2oMGpQIg/JkW2K6Jc0hN5ndlRHmdjhriHz7cg5mL02bgt+d4B6boo/+oYg6P2gQBNYr5iLVzLNG5+l/g1H5+/fqN87//B2bOj65wzMcs50D4UfCSf587Kz/ZfwH2ZrpgsyZmPmF91BMk8jrgBX/6xP+Yf/IFyhzuv9IO6omC9UlhgyVYsT9/gp2vAsctCObCIJP1SdGEDNiWv6ivDvNvvkOZw6VdHKGzPimakAHnnzqAj4BVHELDCb+Ltc9FngBD2H/9/dq5ve2cvOSnXvYws+a0sCMEYPtdMYjdMKZuF3l/VAKLlaMvjwrtx9N/6HAEA8r8BurJAOZcWPbc43v8t5TX/xwzTo8mvCMmDmZ+B/XbxUaNmZjQ+R+j7FnSND36Ot/ut7c7fFMAZQ5OTQBSkH26/IhGZEiXjOZ8g+suQOLcnOEiIKfoMjxhw+V/jFhCetTBUWoyzMFuOyT3yvANDIG0/xd7dUaMfQ8jDo1TwUEqpBTISnMINFzs1ZmlUVie7gfr4zFkgNscdmR0iv5tgnokVFphO/0ERhychoNkXpnKXeDJRN+cHWB3QMyB+ShwIdkEta8xHEKBQYym2dlJFdhGhxEHdHDNAZzKH9A3umAkLLJ/OdlTEHNgwAJORUFn0+mNnwLHN2LVOK0fNF+PAGybg6vIwmzSE4b0KIC/V04X35yTRwOFdLCUDLiIDCshbzC3Dz+pEUnCcdaMk4J6Bqy+BK4yIM7eoKtMi3u9ZWT/clIqkCWHafYpuMkf3pdMN5MGP+sMWzSIOYdVl8CDo6jBjhRVx/HtWqSWyPwryJLD0o/QuhJuQLtONel87d6ByCuoFxT0iuDDL5AXU9Knn/l9A4C3Byn2W8gLgmU9g5xmKVN3unXH+0zErlG1e4fBNQJQsFKAhirkgc8i0Hc6d9GjaWeKvMOCFdDrQY+xMkz0uGKX2lrJ1xbRtExcT23DKhEgiwbubtckZgjpNj3D6/yM1Rp+Lnpi26d0onGAiivgY4ZNmZmyAt0p5uae4wrsZ2dO/v4LxHMLAQpVwMcMO3IXOdH7x/nyTkm4/PcvoqoO8mHA82qW7N1d9CN0dJ4Pm7BP5hckUgETdy3pwXCDrt959TVQDJqIOPgSGCMjPxnOOHOAOwsk1dc+xz8Q4uCpVODgBQP0gTiDW4kG6nASIOXWgmp1AzWrRYJuPvgDPNjxlUdAzNngCJp+SkqcdQmHy111RKPQCyAOTBd2nlD4goDOZBFGVG/J4F5Vjldz3yFbvAm+2cuVmb4mcEcVMME4LrIXEhKQb8EvJrVSas61uaP7yPwR7A6CN6jtbwi/gtc5UnXAy4j+Y9v8swygOv4bRNC3xvDhBVPJ3aNzMEyJleEGQqAY5RSUX76BHqai/OCLJt2lMYotflbzC79w+hOWYy3r8OEs11N8tA3rwkRHF3SfMGfuf/0FFg27E/g8XkqfKD+zq8q4zd4w20IDcnvyMxKu/fr8rQNt4y61EZeLGxq3IiCJQpvRcudqU8jvvH172wlwizpYo4vhLdI78mA6Elbis7noKE8wvA1vtLTTykoWy2t2tJ7qs8IGTTuDOYPS8hRdqkzHlOk/WtodZCgdiFrjToOedzpf8OLyFnyOrss0MJZp9NUsfHdqopY7UOnuCo5p4zgVhl5MfARlbXeqQ69Jff7Ni6s5tava5hzg79rauC8dJ1XrIw9LOwhIR0s7dzOOhsu7ocTVPYdzSTUL1XpL92z0BSCuebTS08qGJveMIcOyPbM17MLWolZt3LQ1T+baTNecKD9XV/S2TT73kL1uena7V99lnlZfqHbrzVHK8zKO1D0QrplaNe8QtWZGfCuP4Vp6xvT01Hg0PW4O63P0m8fT0TilJ7ugYA3r/cx9aEGNz+xWitm1FHZ4Zb1jWZZrJLoDwSq2V3XeKBWBf7mOS4kMfUnnR2NQammrvmHQMp3+yuwYD4Uh+s7uBHB1bbRWMY+i1NMlb7BG0naKR8OlHx+NxG7LRHtfSNq6N1EUGCjGzOOWM8xiBK7RRN4rXgFKzYkmcYsMH+GtLqP6q1ztCAblnlu0LUVrH97gM26u4RxhSWyVe5PwAqVE9N3Q+b/ry99lsy6EFyililLuaejyeub4uPyaN7YAhVL5ZpQyZ/65cIwydHF1OwhzJq1+4/VvawhqYUzWGrvh7Wpm5tFvf8LMnc+Y4a8zGfX65dKrcM9UozColmZ3yTWPe73eNPjn+CaM4BrdUnWw/v38fzuIoVFXXbcYAAAAAElFTkSuQmCC
// ==/UserScript==
(function() {
'use strict';
// 这里填写要匹配的用户名,以英文逗号分隔
// 例如 'aaa','bbb','ccc'
const target_user_list = [
''
]
// ----------------------------------------------------------------------------------------
const MY_COOKIE = document.cookie
// 用户关注列表是否被禁止查看
let focus_list_forbid = false
// 已经搜索过的用户缓存数据
let searched_user_cach = []
// 用户关注的 target_user_list 命中数
let searched_user_target_match_num_cache = []
// 用户关注的具体 target_user
let searched_user_target_match_user_cache = new Map();
// 最大查询分页数 <= 11 (11是微博设置的查看上限)
let max_page = 5
// 命中数
const buf = new ArrayBuffer(4);
const total_match_num = new Int32Array(buf);
// 命中的 user_list
let match_user_list = []
let showFlag = 0
new MutationObserver((mutations) => {
let mutation = mutations[0]
showFlag += 1
if (showFlag % 2 == 0) {
// 移除
document.querySelector('#my_div').remove()
document.querySelector('#my_focus_user_div').remove()
return
}
let popCard = mutation.target
let nameCard = popCard.childNodes[0].childNodes[0].childNodes[2].childNodes[1]
let hrefCard = popCard.childNodes[0].childNodes[1].childNodes[0].childNodes[0].childNodes[1]
let username = nameCard.innerText
let href = hrefCard.href
// 获得uid
let uid = getUserId(href)
// console.log(href)
console.log(username)
search(uid, username)
// 渲染
flushEle(popCard, username)
}).observe(document.querySelector('.popcard'), {
//childList: true,
attributes: true,
//subtree: true,
});
// console.log(Atomics.load(total_match_num, 0))
function flushEle(popCard, name) {
let div = makeFocusDiv(name)
popCard.appendChild(div)
let div_user_list = makeFocusUserListDiv(name)
popCard.appendChild(div_user_list)
}
function getUserId(href) {
// https://weibo.com/u/page/follow/123123123?relate=fans
let l = href.indexOf('follow/')
let r = href.indexOf('?')
let text = href.substring(l+'follow/'.length, r)
return text
}
function makeFocusDiv(name) {
// 获取缓存的命中user数量
let cachedPos = cached(name)
console.log(searched_user_cach)
console.log(searched_user_target_match_num_cache)
let num = 0
if (cachedPos != -1) {
num = searched_user_target_match_num_cache[cachedPos]
} else {
num = '正在请求数据...请稍后'
}
let div = document.createElement('div');
div.id = 'my_div'
if (focus_list_forbid) {
div.textContent = '只有粉丝才能查看关注列表'
} else {
div.textContent = num
}
return div
}
function makeFocusUserListDiv(name) {
let div = document.createElement('div');
div.id = 'my_focus_user_div'
let user_list = ''
let cachedPos = cached(name)
if (cachedPos != -1) {
let u_list = searched_user_target_match_user_cache.get(name)
if (u_list.length > 0) {
u_list.forEach(item => {
const p = document.createElement('p');
p.textContent = item;
div.appendChild(p);
});
}
} else {
}
// div.textContent = user_list
return div
}
// 查询用户关注列表
async function search(uid, name) {
if (cached(name) != -1) {
// do cached job
return
}
focus_list_forbid = false
// 初始化
match_user_list = []
// 遍历关注列表
Atomics.store(total_match_num, 0, 0); // 原子写入
for (var i = 1; i <= max_page; i++) {
await async_fetch(uid, i)
}
console.log("查询结果:" + name + "_" + Atomics.load(total_match_num, 0))
if (focus_list_forbid) {
searched_user_cach.push(name)
searched_user_target_match_num_cache.push('只有粉丝才能查看关注列表')
searched_user_target_match_user_cache.set(name, [])
} else {
searched_user_cach.push(name)
searched_user_target_match_num_cache.push('命中特征用户数量:' + Atomics.load(total_match_num, 0))
searched_user_target_match_user_cache.set(name, match_user_list)
}
}
// 查找缓存数组的下标
function cached(name) {
for (var i in searched_user_cach) {
if (name == searched_user_cach[i]) {
return i
}
}
return -1
}
// 同步请求数据
async function async_fetch(uid, page_num) {
if (focus_list_forbid) {
return
}
var myHeaders = new Headers();
myHeaders.append('Cookie', MY_COOKIE); // 设置Cookie
myHeaders.append("Referer", "https://m.weibo.cn/");
myHeaders.append("Sec-Fetch-Mode", "cors");
myHeaders.append("Accept", "application/json, text/plain, */*");
myHeaders.append("Origin", "https://weibo.com");
myHeaders.append("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36");
myHeaders.append("Client-Version", "v2.40.83");
myHeaders.append("Content-Type", "application/json");
var requestOptions = {
method: 'GET',
headers: myHeaders,
};
var url = 'https://weibo.com/ajax/friendships/friends?page=${page_num}&uid=${uid}'
url = url.replace('${page_num}', page_num).replace('${uid}', uid);
await fetch(url, requestOptions)
.then(response => response.text())
.then(result => fetchPromise(result))
.catch(error => console.log('error', error));
}
async function fetchPromise(result) {
var r = result.indexOf('博主设置仅针对粉丝展示全部关注')
if (r != -1) {
console.log('博主设置仅针对粉丝展示全部关注')
focus_list_forbid = true
return
}
friendsDataSolver(result)
}
// 数据解析
function friendsDataSolver(result) {
console.log('网络请求')
const parsedData = JSON.parse(result);
// 设置最大页数
let total_number = parsedData.total_number
var total_page_size = parseInt(total_number/20)
if (total_page_size < 11) {
max_page = total_page_size
}
var users = parsedData.users
for (var i in users) {
const u = users[i]
let f = isInTargetUserList(u.screen_name)
//console.log(f + ' ' + u.screen_name)
if (f) {
console.log(f + ' ' + u.screen_name)
Atomics.add(total_match_num, 0, 1)
match_user_list.push(u.screen_name)
}
}
}
// 是否命中
function isInTargetUserList(name) {
for (var i in target_user_list) {
if (name == target_user_list[i]) {
return true
}
}
return false
}
})();