# 方法一:分段提取,手动合并
由于微博采用 “虚拟滚动” (Virtual Scroller) 技术所以我们采用分段提取,手动合并的方法。
需要将脚本拆分为三部分:1. 初始化 -> 2. 循环提取 -> 3. 最终导出
# 操作流程
【仅执行一次】在控制台粘贴并运行 “代码1”,初始化一个数据仓库。- 现在,开始
慢慢向下滚动页面。 - 每滚动一两屏,就粘贴并运行 “
代码2”。你会看到控制台打印出新增了多少用户。 - 重复第 3 步,
滚动一点,运行一次代码2,直到滚动到列表的最底部,出现 “没有更多数据了” 的提示。 【仅执行一次】确认你已滚动到底部,最后在控制台粘贴并运行 “代码3”,生成并下载包含所有人的 CSV 文件。
在微博关注列表页面按 F12 打开开发者工具,点击 “控制台” (Console) 运行代码。
# 代码 1:初始化数据仓库 (只在最开始运行一次)
// 代码 1:初始化 | |
window.myFollowingList = []; // 用来存储最终结果 | |
window.myFollowingLinks = new Set(); // 用来去重,确保每个用户只添加一次 | |
console.log("✅ 初始化完成!已创建数据仓库。现在可以开始滚动并使用“代码2”进行提取了。"); |
# 代码 2:提取当前可见用户 (滚动时反复运行)
// 代码 2:提取当前屏幕可见的用户 | |
const CARD_SELECTOR = '.UserFeedCard_userFeedCard_3shKr'; | |
const LINK_SELECTOR = 'a.UserFeedCard_left_2XXOA'; | |
const NICKNAME_SELECTOR = '.UserFeedCard_cla_1QH69 > span'; | |
const userCards = document.querySelectorAll(CARD_SELECTOR); | |
let newCount = 0; | |
userCards.forEach(card => { | |
const linkElement = card.querySelector(LINK_SELECTOR); | |
if (linkElement && linkElement.href) { | |
const userLink = new URL(linkElement.href, window.location.origin).href; | |
// 使用 Set 来判断是否是新用户 | |
if (!window.myFollowingLinks.has(userLink)) { | |
const nicknameElement = card.querySelector(NICKNAME_SELECTOR); | |
const nickname = nicknameElement ? nicknameElement.innerText.trim() : '未知昵称'; | |
window.myFollowingLinks.add(userLink); | |
window.myFollowingList.push({ nickname: nickname, link: userLink }); | |
newCount++; | |
} | |
} | |
}); | |
console.log(`🔎 本次提取新增 ${newCount} 个用户。当前总计 ${window.myFollowingList.length} 个用户。请继续滚动并运行本脚本。`); |
# 代码 3:导出所有数据 (滚动到底部后,最后运行一次)
// 代码 3:生成并下载 CSV | |
if (!window.myFollowingList || window.myFollowingList.length === 0) { | |
console.error("❌ 错误:数据仓库为空,无法导出。请确认您已运行过代码1和代码2。"); | |
} else { | |
console.log(`🚀 即将导出全部分类,总计 ${window.myFollowingList.length} 个用户。`); | |
let csvContent = "序号,用户昵称,个人主页链接\n"; | |
window.myFollowingList.forEach((user, index) => { | |
const safeNickname = user.nickname.replace(/"/g, '""'); | |
csvContent += `${index + 1},"${safeNickname}","${user.link}"\n`; | |
}); | |
const blob = new Blob([new Uint8Array([0xEF, 0xBB, 0xBF]), csvContent], { type: 'text/csv;charset=utf-8;' }); | |
const link = document.createElement("a"); | |
const url = URL.createObjectURL(blob); | |
link.setAttribute("href", url); | |
link.setAttribute("download", `my_weibo_followings_total_${window.myFollowingList.length}.csv`); | |
document.body.appendChild(link); | |
link.click(); | |
document.body.removeChild(link); | |
console.log("✅ 下载完成!"); | |
} |
# 方法二:全自动微博关注列表 API 导出脚本 - 简介与使用说明
# 脚本功能
本脚本用于快速、完整地导出指定微博用户(通常是您自己)的全部关注列表,并将其自动保存为一个 .csv 格式的表格文件。该文件可以用 Excel、WPS 表格或任何文本编辑器打开。
# 核心原理与优势
高效稳定:脚本通过直接调用微博的官方数据接口(API)来获取列表,而非模拟人工在页面上滚动。因此,它的执行速度极快,可以轻松导出数千人的列表,且过程非常稳定。
完整无遗漏:此方法能完美绕过微博主页的 “虚拟滚动” 技术限制,确保可以获取到关注列表中的每一个人,不会像滚动脚本那样出现数据遗漏。
高成功率:由于是直接与数据接口交互,大大减少了对微博服务器的请求次数,能有效避免因操作频繁而被临时限制访问的问题。
数据清晰:导出的 CSV 文件包含序号、用户昵称、用户 UID 以及自动为您拼接好的个人主页链接,方便您后续整理和使用。
# 使用前准备
- 核心要求:运行此脚本前,您必须手动找到您自己的微博 UID(一串代表您身份的数字)。
# 如何使用
- 获取您的 UID:
登录微博,进入您自己的个人主页。
查看浏览器顶部的地址栏。链接通常会是
https://weibo.com/u/1234567890的格式。其中,u/ 后面的那一长串数字(例如 1234567890)就是您的 UID。请将其复制下来。
- 配置脚本:
复制脚本的完整代码。
找到代码最顶部的配置区,将您刚刚复制的 UID 粘贴到 yourUid 变量的引号内,替换掉原来的示例数字。
// 例如,修改为: | |
const yourUid = "1234567890"; |
- 运行脚本:
在任意一个微博页面上(只要是 weibo.com 的域名下即可),按
F12键打开 “开发者工具”。点击 “控制台” (Console) 选项卡。
将您修改好的完整代码粘贴进去,然后按 回车键。
- 下载文件:
脚本会自动开始执行,您可以在控制台看到它的运行进度。
任务完成后,浏览器将自动下载一个名为 微博关注列表_XXX 人.csv 的文件,导出成功!
# 重要提示
本脚本依赖于微博当前的 API 接口设计。如果未来微博的工程师对其进行了修改(例如更改 API 地址、参数或返回的数据结构),此脚本可能会失效。届时,就需要重新进行 “网络侦测”,找到新的 API 信息来更新脚本。
# 全自动脚本
async function exportFollowingsWithManualUID() { | |
// —————————— ▼▼▼【请在这里配置】▼▼▼ —————————— | |
// 1. 请在这里填入您自己的 UID(那串数字)。请保留双引号。 | |
const yourUid = "1234567890"; | |
// —————————— ▲▲▲【配置完成】▲▲▲ —————————— | |
//--- 检查配置是否已修改 --- | |
if (yourUid === "1234567890") { | |
console.error("❌ 请先修改脚本中的 yourUid,填入您自己的UID!"); | |
return; | |
} | |
console.log("🚀 手动配置模式启动!"); | |
console.log(`✅ 已指定UID: ${yourUid}`); | |
//--- 脚本核心逻辑 --- | |
const baseUrl = "https://weibo.com/ajax/profile/followContent"; | |
const masterList = new Map(); | |
let page = 1; | |
let nextCursor = "0"; | |
let hasMore = true; | |
while (hasMore) { | |
try { | |
const apiUrl = `${baseUrl}?page=${page}&next_cursor=${nextCursor}&uid=${yourUid}`; | |
console.log(`正在请求第 ${page} 页 (cursor: ${nextCursor})...`); | |
const response = await fetch(apiUrl); | |
if (!response.ok) throw new Error(`网络请求失败,状态码: ${response.status}`); | |
const data = await response.json(); | |
if (!data.ok || data.ok !== 1) throw new Error(data.msg || "API返回错误状态"); | |
const users = data.data?.follows?.users; | |
if (!users || users.length === 0) { | |
console.log("ℹ️ API返回的用户列表为空,已到达列表末尾。"); | |
hasMore = false; | |
continue; | |
} | |
let newCountInPage = 0; | |
for (const user of users) { | |
if (user && user.id && !masterList.has(user.id.toString())) { | |
const nickname = user.screen_name?.trim() || '未知昵称'; | |
masterList.set(user.id.toString(), nickname); | |
newCountInPage++; | |
} | |
} | |
console.log(`✅ 第 ${page} 页处理完毕,新增 ${newCountInPage} 个用户。当前总数: ${masterList.size}`); | |
page++; | |
nextCursor = data.data?.follows?.next_cursor?.toString() || "0"; | |
if (nextCursor === "0" || newCountInPage === 0) hasMore = false; | |
await new Promise(resolve => setTimeout(resolve, 1000 + Math.random() * 500)); | |
} catch (error) { | |
console.error(`❌ 在请求第 ${page} 页时发生严重错误:`, error.message); | |
console.error("脚本已中断。"); | |
hasMore = false; | |
} | |
} | |
if (masterList.size === 0) { | |
console.warn("⚠️ 任务完成,但未能收集到任何用户数据。"); | |
return; | |
} | |
//--- 生成并下载 CSV 文件 --- | |
console.log(`🚀 数据全部获取完毕!总计 ${masterList.size} 个用户。准备生成CSV文件...`); | |
let csvContent = "序号,用户昵称,用户UID,个人主页链接\n"; | |
let index = 1; | |
for (const [uid, nickname] of masterList.entries()) { | |
const safeNickname = nickname.replace(/"/g, '""'); | |
const userLink = `https://weibo.com/u/${uid}`; | |
csvContent += `${index++},"${safeNickname}","${uid}","${userLink}"\n`; | |
} | |
const blob = new Blob([new Uint8Array([0xEF, 0xBB, 0xBF]), csvContent], { type: 'text/csv;charset=utf-8;' }); | |
const link = document.createElement("a"); | |
const url = URL.createObjectURL(blob); | |
link.setAttribute("href", url); | |
link.setAttribute("download", `微博关注列表_${masterList.size}人.csv`); | |
document.body.appendChild(link); | |
link.click(); | |
document.body.removeChild(link); | |
console.log("✅ 下载完成!"); | |
} | |
// 自动运行主函数 | |
exportFollowingsWithManualUID(); |