1. 项目概述与核心价值

如果你和我一样,每天需要花大量时间在LinkedIn上找人、发消息、看动态,同时还得处理一堆自动化脚本和AI工具,那你肯定明白那种“工具链太长、操作太碎”的痛点。今天要聊的这个 linkedin-cli ,就是专门为解决这个问题而生的。简单说,它是一个命令行工具,让你能用一行命令,完成在LinkedIn上几乎所有的人工操作——从查找联系人、发送消息,到发布动态、分析数据,甚至对接Sales Navigator的高级功能。但它的核心价值远不止“自动化”,而是为AI智能体(Agent)提供了一个标准化的、可编程的接口,让AI能像调用本地API一样,安全、稳定地操作LinkedIn。

为什么说这很关键?在当前的AI工作流中,无论是OpenClaw、Claude Code还是Cursor,它们都擅长处理结构化的数据和指令,但往往卡在“如何与真实世界的Web应用交互”这一步。自己写Selenium脚本?维护成本高,容易被风控。用无头浏览器?IP和指纹管理是噩梦。 linkedin-cli 的底层是 Linked API 服务,它为每个账户分配了一个独立的、带有真实住宅IP的云端浏览器实例。这意味着,当你的AI通过CLI发送一个“发送消息”的指令时,这个指令会在Linked API的云端,由一个模拟真人操作(包括鼠标移动、键盘输入、浏览间隔)的浏览器来执行。你本地不需要跑任何浏览器进程,也不用操心代理池和反爬策略。这对于需要规模化、可编程地使用LinkedIn数据的销售团队、招聘人员,或者任何想将LinkedIn操作集成到自动化流程中的开发者来说,是一个游戏规则的改变。

2. 核心架构与安全机制解析

在深入使用之前,我们必须先理解它的工作原理,这直接关系到使用的安全性和稳定性。很多人在尝试自动化LinkedIn时,第一个担心就是:“我的账号会不会被封?” 这也是 linkedin-cli 设计时首要考虑的问题。

2.1 云端执行与真人模拟

linkedin-cli 本身只是一个轻量级的命令行客户端。它的核心逻辑是:接收你的命令,将其转换为一个标准的API请求,发送给Linked API的后端服务。真正的“重活”都在云端完成。

Linked API的后端为每个用户账户维护一个独立的、持久的浏览器会话。这个浏览器运行在真实的住宅IP后面,并且会模拟人类用户的行为模式。例如,当执行 person fetch (获取个人资料)时,云端浏览器会:

  1. 正常登录到LinkedIn。
  2. 像真人一样等待页面加载(有随机延迟)。
  3. 滚动页面以触发动态内容加载。
  4. 执行鼠标移动和点击来展开“查看更多”部分。
  5. 最后将结构化的数据提取出来,通过API返回给CLI,再由CLI呈现给你。

这种“云端真人模拟”的模式,有几个显著优势:

  • 零本地负担 :你不需要安装Chrome、Chromedriver或任何浏览器驱动。
  • IP与指纹安全 :住宅IP和完整的浏览器环境大大降低了被LinkedIn识别为机器人的风险。
  • 行为合规 :所有操作都遵循Linked API平台配置的速率限制和操作间隔,避免了因操作过快导致的封禁。

2.2 身份验证与令牌管理

安全性另一个核心是身份验证。 linkedin-cli 不直接存储你的LinkedIn用户名和密码。你需要先在 Linked API平台 注册并关联你的LinkedIn账户。平台会为你生成两套令牌(Token):

  1. Linked API Token :这是你账户的全局API密钥,用于标识你的Linked API账户和权限。
  2. Identification Token :这个令牌与你关联的特定LinkedIn账户绑定。它用于在云端浏览器会话中安全地标识你的身份。

CLI通过 linkedin setup 命令让你保存这些令牌。它们被加密后存储在你本地机器的配置文件中(通常是 ~/.linkedin-cli/config.json )。所有后续的API请求都会携带这些令牌。这种设计意味着,即使你的CLI配置泄露,攻击者也无法直接获取你的LinkedIn密码,你只需要在Linked API平台上撤销并重新生成令牌即可。

2.3 操作队列与速率限制

这是防止账号出问题的关键设计。Linked API为每个LinkedIn账户维护一个操作队列。即使你通过脚本瞬间发出10个 message send 命令,这些命令也会被依次放入队列,一个一个地、以符合人类行为的速度执行。你无法绕过这个队列。

此外,在Linked API的仪表板上,你可以为每个账户设置每日/每周的操作上限(例如,每日最多发送50条消息,最多搜索200次)。一旦达到上限,CLI会返回 limitExceeded 错误,强制你停止操作。这不仅是技术限制,更是主动的风险控制策略,引导你在LinkedIn允许的范围内进行自动化。

注意 :永远不要试图修改客户端或寻找绕过队列和限制的方法。这些限制是保护你账号安全的“护栏”。超出合理频率的自动化操作是LinkedIn明确禁止的,并可能导致账号永久封禁。Linked API的设计就是在合规的前提下最大化自动化效率。

3. 环境配置与多账户管理实操

理解了原理,我们开始动手。安装非常简单,因为它是一个Node.js包。

npm install -g @linkedapi/linkedin-cli

安装后,直接在终端输入 linkedin ,应该能看到帮助信息。接下来是最关键的一步:认证配置。

3.1 初始账户设置

运行 linkedin setup ,CLI会以交互方式引导你:

  1. 提示你输入 Linked API Token
  2. 提示你输入 Identification Token

这两个令牌都需要从 Linked API Dashboard 获取。登录后,通常可以在“API Keys”或“Settings”部分找到。将它们分别粘贴进去即可。

对于自动化脚本(如CI/CD或无人值守的Agent),你可以使用非交互模式一次性完成设置:

linkedin setup --linked-api-token=你的_api_token --identification-token=你的_identification_token

设置成功后,CLI会保存这个账户,并默认将其设为“活跃账户”。

3.2 多账户切换与管理实战

在实际业务中,我们经常需要管理多个LinkedIn账号(例如,个人号、工作号、不同业务线的号)。 linkedin-cli 对此的支持非常优雅。

1. 添加第二个账户: 只需再次运行 linkedin setup ,输入另一套令牌。CLI会为你保存一个新的账户配置。你可以通过 linkedin account list 查看所有已保存的账户,当前活跃的账户前面会有一个 * 标记。

2. 切换活跃账户: 使用 linkedin account switch “账户名” 。这里的“账户名”是CLI自动生成或你之后重命名的名字,支持模糊匹配(不区分大小写)。例如,如果你的账户列表里显示 Vlad (vlad@company.com) ,你可以用 linkedin account switch vlad 来切换。

3. 为单条命令指定账户: 这是非常实用的功能。你不需要全局切换,就能用特定账户执行操作。在任何命令后加上 --account “账户名” 参数即可。

linkedin person fetch https://www.linkedin.com/in/someone --account “MyWorkAccount”

4. 账户维护:

  • 更新令牌 :如果你的令牌在Dashboard上重置了,用 linkedin account update [账户名] 来更新本地配置。
  • 重命名账户 :使用 linkedin account rename “旧名” --name “新名” 给账户一个更易识别的名字。
  • 删除账户 linkedin reset 删除当前活跃账户, linkedin reset --all 慎用 ,会删除所有账户配置。

3.3 输出格式与控制

CLI提供两种输出模式,这对AI Agent集成至关重要:

  • 人类可读模式(默认) :当输出到终端(TTY)时,它以清晰的键值对和表格形式展示数据,方便你直接阅读。
  • JSON模式( --json :输出纯JSON结构,方便用 jq 等工具解析。 当CLI检测到标准输出不是终端(例如被管道重定向)时,会自动启用JSON模式。

结合 --quiet ( -q ) 标志可以抑制所有进度提示和错误输出(stderr),只保留纯净的JSON数据到stdout,这是为AI Agent设计的理想数据接口。

# AI Agent 友好命令示例:获取姓名和职位,输出纯净JSON
linkedin person fetch https://www.linkedin.com/in/example --json --fields name,headline -q
# 输出: {"success": true, "data": {"name": "John Doe", "headline": "CTO at Example Corp"}}

# 配合 jq 进行数据处理
linkedin person search --term “Engineer” --json -q | jq ‘.data[].name’

4. 核心功能命令深度解析与实战脚本

CLI的功能模块覆盖了LinkedIn的核心交互场景。我们挑几个最常用的,深入看看怎么用,以及背后的细节。

4.1 人与公司信息获取 ( person fetch / company fetch )

这是最基本也是最重要的功能。 person fetch 不仅仅是抓取公开页面。

基础获取:

linkedin person fetch https://www.linkedin.com/in/vprudnikoff

这会返回个人资料的基础信息:姓名、头像、职位、关于、地区等。

深度资料获取: 通过添加标志位,你可以获取结构化的深度数据,这些数据对于销售线索建档或竞品分析极其有用。

linkedin person fetch https://www.linkedin.com/in/vprudnikoff \
  --experience \      # 获取工作经历(公司、职位、时长)
  --education \       # 获取教育经历
  --skills \          # 获取技能标签
  --languages \       # 获取语言能力
  --json              # 输出为JSON

返回的 experience 数组里,每段经历都包含公司、职位、起止时间、地点甚至描述,可以直接导入你的CRM。

动态内容获取: 你甚至可以获取这个人最近的动态,用于分析其关注点和活跃度。

linkedin person fetch https://www.linkedin.com/in/vprudnikoff \
  --posts \           # 获取最近发布的帖子
  --posts-limit 5 \   # 限制5条
  --posts-since 2024-06-01T00:00:00Z \ # 获取六月以来的帖子
  --comments \        # 获取最近发表的评论
  --reactions         # 获取最近的反应(点赞等)

company fetch 命令类似,可以获取公司详情、员工列表(可过滤)、决策者信息以及公司发布的帖子。

实战技巧:构建一个线索分析脚本 假设你是销售,想快速了解一个目标公司的技术团队情况:

#!/bin/bash
COMPANY_URL=“https://www.linkedin.com/company/tech-startup”

# 1. 获取公司基本信息
echo “=== 公司概况 ===”
linkedin company fetch $COMPANY_URL --json -q | jq -r ‘.data | “名称: \(.name)\n描述: \(.description)\n规模: \(.staffCountRange)\n行业: \(.industries)”’

# 2. 获取前10名工程师员工
echo -e “\n=== 工程师员工列表 ===”
linkedin company fetch $COMPANY_URL --employees --employees-position “Engineer” --employees-limit 10 --json -q | jq ‘.data.employees[] | {name, headline, profileUrl}’

这个脚本能让你在几秒钟内获得一份初步的侦察报告。

4.2 高级搜索 ( person search / company search )

搜索功能是潜在客户开发(Prospecting)的利器。它允许你使用LinkedIn的高级搜索过滤器,但通过命令行实现。

找人搜索示例:

# 寻找旧金山地区的RevOps工程师
linkedin person search --term “revops engineer” --locations “San Francisco, CA” --json

# 寻找当前或曾在Linked API工作过的工程师
linkedin person search --current-companies “Linked API” --previous-companies “Linked API” --position “Engineer” --json

# 结合多个过滤器:MIT毕业,在软件行业,最多返回50条
linkedin person search --schools “Massachusetts Institute of Technology” --industries “Software Development” --limit 50 --json

找公司搜索示例:

# 寻找位于柏林的中小型软件公司
linkedin company search --industries “Software Development” --locations “Berlin, Germany” --sizes “11-50,51-200” --json

# 寻找特定规模的金融科技公司
linkedin company search --term “fintech” --sizes “201-500,501-1000” --json

注意事项 :搜索是一个相对较慢的操作,因为云端浏览器需要模拟人工输入关键词、应用过滤器、翻页抓取结果。一次复杂的搜索可能需要30秒以上。务必合理使用 --limit 参数,避免不必要的长时间等待。此外,搜索结果的质量和数量受限于你LinkedIn账户的搜索权限(免费版和高级版的区别在云端浏览器中同样适用)。

4.3 消息与连接管理 ( message send , connection send )

自动化沟通需要格外谨慎。 linkedin-cli 提供了相关功能,但必须负责任地使用。

发送消息:

linkedin message send https://www.linkedin.com/in/recipient “Hi [First Name], I came across your work on [Specific Project/Topic]. Really impressive! I’d love to connect and learn more.”
  • 字符限制 :消息文本最多1900字符。
  • 最佳实践 :始终个性化。虽然CLI能发消息,但模板化的垃圾信息是LinkedIn打击的重点,也会损害你的声誉。建议将CLI与一个包含个性化变量(如对方公司、职位、最近动态)的脚本结合使用。

发送连接请求:

linkedin connection send https://www.linkedin.com/in/recipient --note “Hi, I see we’re both interested in AI agents. Would love to connect!”
  • 个性化备注 --note 参数至关重要。带备注的连接请求通过率远高于空白请求。
  • 邮箱参数 :对于设置了“仅通过邮箱添加”的用户,你需要使用 --email 参数提供邮箱地址。

管理现有连接:

  • connection list :列出你的所有连接,并可进行过滤(如按公司、职位)。
  • connection pending :查看你发出的、尚未被接受的请求。
  • connection withdraw :撤回待处理的请求。
  • connection remove :移除已建立的连接。

消息获取: message get 命令可以获取你与某个联系人的对话历史,支持按时间筛选 ( --since )。这对于将对话内容同步到外部CRM或支持AI客服场景非常有用。

4.4 内容互动与数据分析 ( post create , stats )

发布帖子:

# 发布纯文本帖子
linkedin post create “Excited to announce our new feature! 🚀 It helps teams automate…”

# 发布带图片的帖子
linkedin post create “Check out our team offsite!” --attachments “https://mycompany.com/photo1.jpg:image” --attachments “https://mycompany.com/photo2.jpg:image”

# 以公司页面身份发布(需要你是该页面的管理员)
linkedin post create “We‘re hiring a Senior Backend Engineer!” --company-url https://www.linkedin.com/company/my-company
  • 附件规则 :最多9张图片,或1个视频,或1个文档。不同类型不能混用。 url:type:name 格式中的 name 是可选的文档显示名称。

帖子互动:

# 点赞一个帖子
linkedin post react https://www.linkedin.com/posts/username_activity-123 --type like

# 以公司身份发表评论
linkedin post comment https://www.linkedin.com/posts/username_activity-123 “Great insights, especially the point about scalability!” --company-url https://www.linkedin.com/company/my-company

数据统计:

  • stats ssi :获取你的LinkedIn社交销售指数(SSI),这是一个衡量你个人品牌销售影响力的分数。
  • stats performance :获取个人资料的数据表现,如近期谁看了你的资料、帖子展示次数、搜索出现次数。
  • stats usage :查询你在Linked API平台上的用量统计,用于监控成本和API调用情况。

这些数据对于衡量你的社交销售策略和自动化效果非常有帮助。

5. Sales Navigator高级功能集成

如果你订阅了LinkedIn Sales Navigator, linkedin-cli 通过 navigator 子命令暴露了其更强大的搜索和过滤能力。 请注意,使用这些功能要求你的Linked API账户所关联的LinkedIn账号拥有有效的Sales Navigator订阅。

Sales Navigator搜索的强大之处在于更精细的过滤器 ,例如:

  • --years-of-experience :按工作年限过滤人选(如 moreThanTen )。
  • --revenue-min / --revenue-max :按公司年收入范围过滤公司。

示例:寻找资深决策者

# 寻找美国地区,工作经验10年以上,职位是CEO或副总裁的人选
linkedin navigator person search \
  --locations “United States” \
  --years-of-experience “moreThanTen” \
  --position “CEO,VP,Vice President” \
  --limit 25 \
  --json

示例:定位特定规模和高收入公司

# 寻找年收入在1000万到1亿美元之间,规模在51-200人的科技公司
linkedin navigator company search \
  --industries “Information Technology & Services” \
  --sizes “51-200” \
  --revenue-min 10 \   # 单位:百万美元
  --revenue-max 100 \
  --json

发送InMail: Sales Navigator允许你向非联系人发送消息(InMail)。命令与普通消息类似,但 必须 包含主题行。

linkedin navigator message send https://www.linkedin.com/in/prospect \
  --subject “Introduction from [Your Company]” \
  “Hi [Name], I noticed your work in [Field]. Our team at [Your Company] is building [Something Relevant]. Would you be open to a brief chat next week?”

使用Sales Navigator功能时,搜索和资料获取的深度、准确度通常比普通LinkedIn搜索更高,但API调用的成本(或计入限额)也可能更高,具体需参考Linked API的定价方案。

6. 自定义工作流与AI智能体集成

这是 linkedin-cli 最强大的部分,它允许你将多个LinkedIn操作组合成一个原子的、可重试的“工作流”。这对于复杂的、多步骤的自动化场景(如:找到目标公司 -> 获取其工程师列表 -> 向每位工程师发送个性化连接请求)至关重要。

6.1 工作流的概念与优势

一个“工作流”是一个JSON文件,定义了一系列要按顺序执行的LinkedIn操作。与单独执行多个CLI命令相比,工作流有两大优势:

  1. 原子性与状态管理 :工作流作为一个整体提交给Linked API,并获得一个唯一的 workflowId 。你可以通过这个ID查询整个工作流的状态(进行中、成功、失败)。如果中途因网络等问题失败,你可以根据ID进行恢复或重试,而不是管理一堆独立的命令状态。
  2. 数据传递 :工作流中前一个步骤的输出,可以作为后一个步骤的输入。例如,你可以先搜索公司,然后将搜索到的公司URL列表,自动传递给下一个“获取公司员工”的步骤。

6.2 构建与运行工作流

工作流JSON需要遵循Linked API定义的 模式 。一个简单的示例如下:

{
  “version”: “1”,
  “actions”: [
    {
      “type”: “person.search”,
      “name”: “findProspects”,
      “params”: {
        “term”: “Head of Marketing”,
        “locations”: “London, UK”,
        “limit”: 5
      }
    },
    {
      “type”: “connection.send”,
      “name”: “connectWithProspects”,
      “params”: {
        “personUrls”: “{{actions.findProspects.output.data[*].profileUrl}}”,
        “note”: “Hi, I see you‘re a marketing leader in London. Love to connect and exchange ideas!”
      },
      “dependsOn”: [“findProspects”]
    }
  ]
}

这个工作流包含两个动作:1) 搜索在伦敦的营销负责人;2) 向搜索到的前5个人发送连接请求。第二个动作的 personUrls 参数通过模板 {{actions.findProspects.output.data[*].profileUrl}} 从第一个动作的输出中动态获取。

运行工作流:

# 从文件运行
linkedin workflow run --file my-workflow.json

# 从标准输入运行(便于脚本化)
cat my-workflow.json | linkedin workflow run

提交后,CLI会返回一个 workflowId

查询工作流状态:

# 查询状态
linkedin workflow status <workflowId>

# 阻塞等待,直到工作流完成(成功或失败)
linkedin workflow status <workflowId> --wait

当工作流执行完毕,你可以获取到所有步骤的聚合输出。

6.3 与AI智能体的深度结合模式

linkedin-cli 的设计哲学是“AI-Agent First”。它的以下特性使其成为AI智能体的完美执行器:

  1. 结构化输出( --json :AI可以轻松解析JSON,提取所需字段。
  2. 纯净错误流( --quiet :AI不会被进度条或调试信息干扰。
  3. 明确的退出码 :AI可以根据退出码判断是业务错误(如人没找到,exit 0但 success: false )还是系统错误(如网络问题,exit 非0)。
  4. 工作流作为“原子动作” :AI可以将一个复杂的多步LinkedIn任务(如“研究X公司并联系其CTO”)规划并打包成一个工作流JSON,然后交给CLI去可靠地执行。AI无需关心每个步骤的重试、状态跟踪。

一个AI Agent使用场景设想: 你告诉AI助手:“帮我找出旧金山最近A轮融资的AI初创公司CEO,并草拟一份个性化的合作邀请。” AI助手可能会内部执行以下逻辑:

  1. 调用 linkedin company search 和外部融资数据库API,筛选出目标列表。
  2. 对每个公司,调用 linkedin company fetch --dms 获取决策者(CEO)信息。
  3. 根据CEO的背景和公司业务,利用LLM生成一段个性化邀请文案。
  4. 构建一个包含多个 navigator.message.send 动作的工作流JSON。
  5. 调用 linkedin workflow run 提交该工作流。
  6. 定期调用 linkedin workflow status 检查进度。

在这个过程中,AI负责高层的策略、判断和内容生成,而 linkedin-cli 负责安全、合规、可靠地执行所有底层的、具体的LinkedIn操作。

7. 常见问题、错误排查与性能优化

在实际使用中,你肯定会遇到各种情况。这里记录了一些典型问题和我的处理经验。

7.1 认证与令牌问题

  • 错误: Invalid or missing tokens (退出码 2)

    • 原因 :本地存储的令牌失效或未设置。
    • 解决 :运行 linkedin account update 重新输入令牌。如果问题依旧,去Linked API Dashboard检查令牌是否被重置或撤销,然后使用新的令牌更新。
  • 错误: LinkedIn account issue (退出码 4)

    • 原因 :关联的LinkedIn账户在平台端出现问题,如需要重新登录、被限制或封禁。
    • 解决 :登录Linked API Dashboard,检查该LinkedIn账户的状态。通常可能需要在该Dashboard上重新授权或解决LinkedIn端的验证问题。

7.2 速率限制与操作队列

  • 错误: limitExceeded (在JSON输出的error中)

    • 原因 :你在Linked API Dashboard上为该账户设置的操作次数限额(每日/每周)已用完。
    • 解决 :等待限额重置(通常是UTC时间午夜),或在Dashboard上调整限额(如果套餐允许)。 切勿试图绕过此限制。
  • 命令执行非常慢,或者感觉卡住了

    • 原因 :这是正常现象,不是错误。Linked API为了模拟真人行为,每个操作都有内置延迟。同时,你的命令可能排在队列后面。
    • 排查 :复杂的操作(如深度搜索、获取大量帖子)本身就需要几十秒。你可以通过查看命令是否有进度输出(除非用了 -q )来判断是否在运行。使用 --quiet 标志时,请耐心等待命令完成。

7.3 网络与超时问题

  • 错误: Network error (退出码 7) 或超时

    • 原因 :你的网络到Linked API服务,或Linked API的云端浏览器到LinkedIn网站出现连接问题。
    • 解决
      1. 检查你的本地网络。
      2. 重试命令。对于非等幂操作(如 message send ),重试前要小心,可能造成重复消息。
      3. 如果是工作流,使用 linkedin workflow status <workflowId> 检查其状态,看是否部分完成。
  • 错误: Workflow timeout (退出码 8)

    • 原因 :一个工作流的执行时间超过了系统限制(通常很长,比如30分钟)。
    • 解决 :你会得到一个 workflowId 。使用 linkedin workflow status <workflowId> --wait 可以继续等待或获取最终结果。考虑将过大的工作流拆分成几个小的工作流。

7.4 数据与参数问题

  • 返回的某些字段是 null 或空数组 []

    • 原因 :这不是错误。LinkedIn用户可能没有填写某些信息(如技能、语言),或者你的账户权限不足以查看某些数据(如非联系人的完整经历)。CLI会如实返回可用数据,缺失的字段用 null 表示。
    • 应对 :在你的处理脚本中,做好空值判断。
  • URL格式问题

    • 注意 :CLI会标准化返回的URL(统一为 https://www.linkedin.com/... 格式)。但你输入给CLI的URL可以是LinkedIn的各种格式(如移动端URL),CLI内部会尝试处理。

7.5 性能优化与最佳实践

  1. 按需获取数据 :大量使用 --fields 参数。如果你只需要姓名和职位,就不要获取完整的经历、教育和帖子。这能显著减少响应时间和数据流量。

    linkedin person fetch <url> --json --fields name,headline,currentCompany
    
  2. 善用过滤条件 :在搜索和列表命令中,尽可能使用 --current-companies --positions 等过滤器在服务端缩小结果集,而不是获取全部数据后再在本地过滤。

  3. 理解异步性与队列 :将 linkedin-cli 想象成一个“任务提交系统”。提交后,你可以去做别的事情,或者通过 workflow status 异步查询结果。不要用同步阻塞的思维去编写紧循环执行的脚本。

  4. 日志与监控 :对于重要的自动化流程,建议将CLI的JSON输出(特别是包含 success: false 的错误信息)记录到日志系统中,以便后续审计和问题排查。

  5. 合规是生命线 :再次强调,所有自动化操作都必须遵守LinkedIn的用户协议。利用好Linked API内置的队列和限制功能,它们是你的保护伞。避免发送大量雷同的消息,始终追求有意义的互动。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐