用requests+BeautifulSoup提取外部链接最可靠,需处理相对路径(urljoin)、协议补全、无效协议过滤、域名比对及去重;JS渲染页面才需Selenium。

直接用 requests + BeautifulSoup 就能可靠提取,但必须处理相对路径、协议补全、重复去重和反爬基础防护,否则拿到的链接大概率不可用或漏掉一大半。
用 BeautifulSoup 解析 a 标签的 href 属性最稳妥
别信正则匹配 href=,HTML 结构多变(换行、单双引号、属性顺序),正则极易漏或误匹配。用 BeautifulSoup 是标准解法:
-
find_all('a', href=True)确保只取有href属性的链接,过滤掉空值或 JS 伪链接 - 对每个
link.get('href')值立刻做清洗:用strip()去首尾空白,再跳过javascript:、mailto:、#开头的无效协议 - 注意有些链接写成
//example.com/path(协议相对 URL),需手动补https:前缀才能构成完整 URL
用 urllib.parse.urljoin() 处理相对路径是刚需
网页里大量链接是相对路径(如 /about、../contact.html),直接拼接会出错。必须用 urljoin() 基于原始页面 URL 做解析:
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
- 传参顺序不能错:
urljoin(base_url, href_value),其中base_url是你requests.get()的那个完整 URL(含协议和路径,不含查询参数) - 如果原始页面 URL 是
https://site.com/blog/,而href是post/123,urljoin()会正确生成https://site.com/blog/post/123 - 若不处理,直接字符串拼接会得到
https://site.com/blog//post/123这类错误路径
提取后必须过滤非外部域名链接
“外部链接”指目标域名与当前页面域名不同的链接。光靠 href 字符串判断不准,得用 urllib.parse.urlparse() 拆解:
立即学习“Python免费学习笔记(深入)”;
- 先用
urlparse(current_url).netloc提取当前页域名(如example.com) - 对每个解析后的完整链接再调一次
urlparse(link).netloc,比较二者是否相等 - 注意子域名差异:
blog.example.com和example.com算不同域名;www.example.com和example.com视业务需求决定是否合并(通常算外部) - 别忘了过滤
data:、tel:等非 HTTP 协议链接,它们根本不是“外部链接”
简单脚本示例(带基础错误处理)
import requests
from bs4 import BeautifulSoup
from urllib.parse import urlparse, urljoin
<p>def extract_external_links(url):
try:
resp = requests.get(url, timeout=10)
resp.raise_for_status()
except Exception as e:
print(f"请求失败: {e}")
return []</p><pre class="brush:php;toolbar:false;">soup = BeautifulSoup(resp.text, 'html.parser')
base_domain = urlparse(url).netloc
external_links = set()
for link in soup.find_all('a', href=True):
href = link['href'].strip()
if not href or href.startswith(('javascript:', 'mailto:', '#')):
continue
full_url = urljoin(url, href)
parsed = urlparse(full_url)
if parsed.scheme not in ('http', 'https') or not parsed.netloc:
continue
if parsed.netloc != base_domain:
external_links.add(full_url)
return list(external_links)使用示例
links = extract_external_links("https://www.php.cn/link/1536687004241eb9faeee0e227b58c60") print(len(links), "个外部链接")
真正麻烦的是 JavaScript 渲染的页面(比如 React SPA),requests 拿不到动态插入的链接——这时候得换 Selenium 或 Playwright,但开销大、启动慢、容易被识别。多数静态站点用上面方法足够,别一上来就上浏览器自动化。

















