别再裸奔了!用 playwright-stealth 完美绕过 LinkedIn 反爬检测,自动化修改个人信息
这几天折腾 LinkedIn 的自动化,头皮都要挠破了。需求其实很简单:写个脚本定时去更新自己的 LinkedIn 个人简介(Headline 和 About),顺便抓一下私信里的猎头消息。
一开始我觉得这事儿有手就行,掏出祖传的 Playwright 一把梭,结果啪啪打脸。LinkedIn 的反爬和风控策略简直变态:
- WebDriver 标记检测:原生的无头浏览器一上去,甚至还没开始动作,直接给你弹个验证码或者直接封 Session。
- React 合成事件拦截:你以为用
page.evaluate()写点 JS 去改 DOM 的value就能填表单?天真!前端的 React 根本不认,你哪怕把输入框的值改了,一提交还是空的。
折腾了两天,最终摸索出了一套本地接管浏览器 + Playwright Stealth + 纯原生模拟按键的终极组合拳,完美绕过检测。这里给大家详细复盘一下,少走弯路。
核心思路:放弃无头,接管真实浏览器
绝大多数反爬检测都在查你的“指纹”。如果你每次都新起一个干净的无头浏览器,还要去模拟登录,被干掉的几率极高。
老司机的做法是:在本机以“开启调试端口”的方式,启动一个真实的 Chrome,然后再用 Playwright 连上去。这样你现成的 Cookie、登录态全都在,且不会带有明显的自动化指纹。再加上 playwright-stealth 的掩护,基本上稳如老狗。
第一步:环境与插件安装
你需要装一下 playwright 和 stealth 插件:
pip install playwright
pip install playwright-stealth
第二步:带调试端口启动 Chrome
这一步千万别漏。你需要关掉现有的所有 Chrome 窗口,然后从命令行启动它,并指定调试端口。
Mac/Linux 环境:
# 指定一个用户数据目录,避免和日常使用的冲突导致锁死
google-chrome-stable --remote-debugging-port=9222 --user-data-dir=/tmp/chrome_debug_profile
Windows 环境:
chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\chrome_debug"
启动之后,你可以手动在这个弹出的浏览器里打开 LinkedIn,把账号密码登录好。
第三步:Python 脚本实战,修改 LinkedIn Headline
准备工作做完,直接上代码。下面这段代码会连接到刚刚开启的 Chrome,自动访问 LinkedIn 个人资料页,并把 Headline 修改为我们指定的文字。
from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync
import time
def update_linkedin_headline(new_headline):
with sync_playwright() as p:
# 1. 核心!连接到已经启动并登录好 LinkedIn 的本地 Chrome
browser = p.chromium.connect_over_cdp('http://127.0.0.1:9222')
# 2. 获取当前的上下文并新建页面
context = browser.contexts[0]
page = context.new_page()
# 3. 注入 Stealth 伪护脚本,抹除 WebDriver 指纹!
stealth_sync(page)
print("正在访问 LinkedIn 个人主页...")
# 注意把这里的 url 换成你自己的 profile 链接
page.goto('https://www.linkedin.com/in/me/')
page.wait_for_load_state('domcontentloaded')
# 停顿一下,模拟人类的加载等待
time.sleep(3)
# 4. 点击编辑按钮 (这里的选择器可能因为 LinkedIn 的改版而变化,请根据实际情况微调)
# LinkedIn 的前端非常复杂,建议使用 aria-label 或 has-text 来稳定定位
edit_btn = page.locator('button[aria-label="Edit intro"]')
if edit_btn.is_visible():
edit_btn.click()
time.sleep(2)
else:
print("找不到编辑按钮!")
return
# 5. 修改 Headline
# 【坑点警告】绝对不要用 page.evaluate() 去改 value!
# 必须用原生的 .fill() 或者模拟键盘按键,否则 React 不会触发 onChange 事件!
headline_input = page.locator('input[name="headline"]')
headline_input.click() # 先聚焦
# 清空原内容并填入新内容
headline_input.fill(new_headline)
print(f"已填入新 Headline: {new_headline}")
time.sleep(1)
# 6. 点击保存
save_btn = page.locator('button').filter(has_text='Save')
if save_btn.count() > 0:
save_btn.last.click()
print("保存完毕!")
time.sleep(3)
else:
print("没找到保存按钮")
# 收工,断开连接(不会关闭浏览器)
page.close()
browser.disconnect()
if __name__ == '__main__':
update_linkedin_headline("AI Agent Developer | System Architecture | MLOps")
踩坑总结
代码看起来不长,但全是血泪教训:
- 不要用 DOM 注入去修改输入框:LinkedIn 这种 React 重度依赖的网站,监听的是底层事件。纯原生操作
.fill()会模拟一连串的输入事件,这样“保存”按钮才能正常亮起。 - Stealth 插件是保命符:加了
stealth_sync(page),后台查你的navigator.webdriver永远是 false,查插件列表也能模拟出正常的浏览器环境。对于日常抓抓猎头私信,甚至自动回复,这招百试百灵。
总之,以后凡是遇到封控严格的站,别头铁用纯脚本去硬刚。本机接管 + Stealth 伪装 + 原生键盘模拟,才是现代爬虫和自动化的终极出路!
遇到问题欢迎在评论区交流,如果有更好的路子也请不吝赐教。
更多推荐
所有评论(0)