如何检测受保护链接有效性?解决Twitter登录及反爬等问题
解决方案
处理验证码/反爬站点的通用方案
单纯用requests发请求绕不开验证码或反爬机制,推荐用无头浏览器(比如Playwright、Selenium)——它们能完整渲染页面JS,应付基础反爬,复杂验证码(比如滑块)可能需要额外处理,但大部分场景足够用。
举个Playwright的实现例子:
from playwright.sync_api import sync_playwright import re def check_link_with_browser(url): with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() try: page.goto(url, wait_until="domcontentloaded") status_code = page.request.last_request.response.status if status_code >= 400: return f"失败: {status_code}" return "成功" except Exception as err: return f"错误: {str(err)}" finally: browser.close() # 和原脚本整合使用 with open(filename, "r", encoding="utf-8") as file: for line in file: for m in re.finditer(r'https?://[^\s"]+', line): result = check_link_with_browser(m[0]) print(f"{m[0]}: {result}")
Twitter链接的处理方案
Twitter反爬严格,直接模拟登录容易被封,优先用官方API,实在要模拟登录再用无头浏览器。
1. 官方API方式(最稳定合规)
先申请Twitter开发者账号,创建应用拿到Bearer Token,然后调用API检查推文状态:
import requests BEARER_TOKEN = "你的Bearer Token" def check_twitter_link(tweet_url): # 从URL里抠出推文ID,比如https://twitter.com/user/status/123456789 -> 123456789 tweet_id = tweet_url.split("/")[-1] api_url = f"https://api.twitter.com/2/tweets/{tweet_id}" headers = {"Authorization": f"Bearer {BEARER_TOKEN}"} response = requests.get(api_url, headers=headers) if response.status_code == 200: return "推文存在" elif response.status_code == 404: return "推文已删除/不存在" else: return f"API请求错误: {response.status_code}"
这种方式完全符合Twitter规则,不会触发反爬,是首选。
2. 无头浏览器模拟登录(仅应急用)
如果必须模拟登录访问,用Playwright保存登录状态,之后复用:
from playwright.sync_api import sync_playwright def save_twitter_login_state(): # 首次运行需要手动登录,所以先关掉无头模式 with sync_playwright() as p: browser = p.chromium.launch(headless=False) context = browser.new_context() page = context.new_page() page.goto("https://twitter.com/login") # 手动完成登录(输账号密码、过验证码) # 登录成功后把状态存到文件 context.storage_state(path="twitter_login_state.json") browser.close() def check_twitter_link_with_login(tweet_url): with sync_playwright() as p: browser = p.chromium.launch(headless=True) # 加载之前保存的登录状态 context = browser.new_context(storage_state="twitter_login_state.json") page = context.new_page() try: page.goto(tweet_url, wait_until="domcontentloaded") # 检查是否还在登录状态,比如找侧边栏的账号切换按钮 if page.locator('div[data-testid="SideNav_AccountSwitcher_Button"]').is_visible(): # 检查推文是否存在,看有没有空状态提示 if page.locator('div[data-testid="empty_state_header_text"]').is_visible(): return "推文不存在" return "访问成功" else: return "登录状态过期,需要重新保存" except Exception as err: return f"错误: {str(err)}" finally: browser.close() # 第一次运行先保存登录状态 save_twitter_login_state() # 之后直接调用检查函数就行
⚠️注意:这种方式有账号被限制的风险,不要频繁请求,尽量用API方案。
原脚本的小优化
- 加个集合存已经检查过的URL,避免重复请求
- 每次请求之间加个1-2秒的延迟,防止被目标网站封IP
- 把链接分类(Twitter、普通站点),针对性用不同检查逻辑
内容的提问来源于stack exchange,提问作者Alex O
相关产品推荐
相关产品推荐

