You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用Selenium的情况下爬取LinkedIn无限滚动页面?

解决LinkedIn人脉页面无限滚动爬取问题(无需Selenium)

LinkedIn的无限滚动页面确实不会把所有内容塞进初始HTML里,用requests+BeautifulSoup直接爬初始页面自然拿不到全部数据。好在LinkedIn是通过后端API动态加载数据的,我们可以直接调用这些API来获取完整的人脉列表,完全不需要Selenium,非常适合部署成Web服务。

下面是具体的解决方案:

1. 先找到LinkedIn的人脉API端点

首先你需要用浏览器开发者工具抓包,定位加载人脉数据的API:

  • 打开LinkedIn人脉页面并登录账号
  • 按F12打开开发者工具,切换到「Network」标签
  • 滚动页面加载更多人脉,观察出现的XHR/Fetch请求,你会找到类似 https://www.linkedin.com/voyager/api/relationships/connections 的请求
  • 点击这个请求,查看它的「Request Headers」和「Query Parameters」,这些是后续模拟请求的关键信息

2. 核心思路:模拟API请求+分页获取

LinkedIn的人脉API支持分页,通过start(起始位置)和count(单次加载数量)参数控制数据范围(通常count最大设为100效率最高)。我们只需要循环调用这个API,每次递增start的值,直到返回的数据为空。

关键注意事项

  • 认证必须有:LinkedIn的API需要登录状态,最核心的是li_at这个cookie(可以从浏览器的Cookie列表里找到),没有它API会直接返回401未授权。
  • 请求头要模拟浏览器:API会验证请求头里的User-Agent、csrf-token、X-Li-Lang等字段,直接复制浏览器里的请求头即可。

3. 完整代码示例

import requests
import json
import time

def scrape_linkedin_connections(li_at_cookie):
    # 初始化会话,保持登录状态
    session = requests.Session()
    
    # 从浏览器复制的请求头,按需调整
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
        'X-Li-Lang': 'en_US',
        'X-Li-Voyager-Id': 'YOUR_VOYAGER_ID',  # 从浏览器请求头复制
        'csrf-token': 'YOUR_CSRF_TOKEN',        # 从浏览器Cookie或请求头复制
        'Accept': 'application/vnd.linkedin.normalized+json+2.1'
    }
    
    # 设置关键认证cookie
    session.cookies.set('li_at', li_at_cookie)
    
    all_connections = []
    start = 0
    count = 100  # 每次请求最多100条,LinkedIn API的上限
    
    while True:
        try:
            # 构造API请求URL
            api_url = f'https://www.linkedin.com/voyager/api/relationships/connections?count={count}&start={start}'
            response = session.get(api_url, headers=headers)
            
            # 检查请求是否成功
            if response.status_code != 200:
                print(f"请求失败,状态码:{response.status_code},响应内容:{response.text[:200]}")
                break
            
            # 解析JSON响应
            data = json.loads(response.text)
            connection_elements = data.get('elements', [])
            
            # 没有更多数据就退出循环
            if not connection_elements:
                print("已获取全部人脉数据")
                break
            
            # 提取每个人脉的信息(字段可根据需求调整)
            for elem in connection_elements:
                member = elem.get('member', {})
                connection_info = {
                    'full_name': member.get('fullName'),
                    'headline': member.get('headline'),
                    'profile_url': f"https://www.linkedin.com/in/{member.get('publicIdentifier')}" if member.get('publicIdentifier') else None,
                    'avatar_url': None
                }
                
                # 处理头像链接(LinkedIn的头像格式是拼接的)
                picture_data = member.get('picture', {}).get('com.linkedin.common.VectorImage', {})
                if picture_data.get('rootUrl') and picture_data.get('artifacts'):
                    artifact = picture_data['artifacts'][0]
                    connection_info['avatar_url'] = f"{picture_data['rootUrl']}{artifact['fileIdentifyingUrlPathSegment']}"
                
                all_connections.append(connection_info)
            
            # 更新分页参数
            start += count
            print(f"已加载 {len(all_connections)} 条人脉数据")
            
            # 添加请求间隔,避免触发反爬
            time.sleep(2)
            
        except Exception as e:
            print(f"爬取过程中出错:{str(e)}")
            break
    
    return all_connections

# 使用示例:替换成你自己的li_at cookie
if __name__ == "__main__":
    my_li_at_cookie = "YOUR_LI_AT_COOKIE_VALUE"
    connections = scrape_linkedin_connections(my_li_at_cookie)
    print(f"总共获取到 {len(connections)} 个人脉")

4. 部署Web服务的建议

  • 会话管理:因为需要用户提供自己的li_at cookie,你可以设计一个简单的API接口,接收用户的cookie参数,返回爬取的人脉列表。
  • 安全提醒:务必告知用户li_at cookie是敏感信息,相当于登录凭证,不要随意泄露,且cookie会定期过期,需要重新获取。
  • 反爬应对:除了添加请求间隔,还可以随机调整count的值(比如80-100之间),或者轮换User-Agent,降低被封禁的风险。
  • 错误处理:在Web服务中增加更完善的错误捕获,比如返回友好的错误信息给用户,而不是直接抛出异常。

这种方法的优势很明显:不需要启动浏览器,资源占用极低,爬取速度快,完全适合部署成轻量级的Web服务。

内容的提问来源于stack exchange,提问作者Nurdin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 10:02:42