
本文详解如何利用 BeautifulSoup 定位 HTML 中 tel: 链接并提取纯净电话号码,结合 pandas 批量处理客户 ID,生成含 ID 与手机号的结构化 DataFrame。
本文详解如何利用 beautifulsoup 定位 html 中 `tel:` 链接并提取纯净电话号码,结合 pandas 批量处理客户 id,生成含 id 与手机号的结构化 dataframe。
在 Web 数据采集场景中,电话号码常以 <a href="tel:+77777777777"></a> 形式嵌入页面(而非明文显示),需通过解析 href 属性提取。BeautifulSoup 是实现该任务的核心工具,配合 requests 发起请求、pandas 组织结果,可高效构建客户联系方式数据集。
✅ 核心步骤概览
-
发送 HTTP 请求:根据客户 ID 构造 URL(如
https://example.com/client/?id=R_111); -
解析 HTML:定位包含电话链接的容器(如
id="phone"的<div>); <li> <strong>提取 <code>tel:值:查找<a></a>标签的href属性,剥离tel:前缀; -
批量处理:将单 ID 函数扩展至 DataFrame 列(
apply())或列表推导式,生成新列。 -
错误处理必须强化:网络请求易失败(超时、404、反爬),务必用
try/except包裹,并对response.status_code和解析结果做双重校验; -
HTML 结构鲁棒性:若页面结构变动(如
id="phone"改为class="contact-phone"),应同步更新soup.find()条件; -
号码标准化建议:
tel:+77777777777中的+表示国际区号,通常应保留;如需纯数字格式,可用正则re.sub(r'[^0-9+]', '', tel_str)清洗; -
性能优化:对大量 ID,考虑添加请求延迟(
time.sleep(0.5))或使用requests.Session()复用连接; -
合法性前提:确保已获网站授权进行数据采集,遵守
robots.txt及服务条款。
? 改进后的完整代码示例
import requests
import pandas as pd
from bs4 import BeautifulSoup
# 配置请求头(模拟浏览器,避免被拦截)
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
def get_client_phone(client_id):
"""
根据客户 ID 获取对应网页中的电话号码(从 tel: 链接提取)
返回纯净号码字符串(如 '77777777777'),失败时返回 None
"""
url = f"https://example.com/client/?id={client_id}"
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # 抛出非200状态异常
except requests.RequestException as e:
print(f"请求失败 {client_id}: {e}")
return None
soup = BeautifulSoup(response.text, "html.parser")
# 精准定位:查找 id="phone" 的 div,再找其内部的 <a href="tel:..."> 元素
phone_div = soup.find("div", id="phone")
if not phone_div:
print(f"未找到 phone 容器(ID: {client_id})")
return None
phone_link = phone_div.find("a", href=True)
if not phone_link or not phone_link["href"].startswith("tel:"):
print(f"未找到有效的 tel 链接(ID: {client_id})")
return None
# 提取并清洗号码:移除 tel:,可选地去掉 '+'(按需保留国际前缀)
raw_number = phone_link["href"][4:] # 跳过 'tel:'
# 若需去除 '+' 且仅保留数字,可用:re.sub(r'\D', '', raw_number)
return raw_number
# ✅ 方式一:从现有 DataFrame 新增 Phone 列(推荐)
data = {
"Date": ["20240514 May, 14 22:00", "20240514 May, 14 23:00"],
"ID": ["R_111", "R_222"],
"Comment": ["Le client ne répond pas", None]
}
df = pd.DataFrame(data)
df["Phone"] = df["ID"].apply(get_client_phone) # 自动广播,简洁高效
# ✅ 方式二:独立构造新 DataFrame
client_ids = ["R_111", "R_222"]
result_df = pd.DataFrame([
{"ID": cid, "Phone": get_client_phone(cid)}
for cid in client_ids
])
print(df)</a>
⚠️ 注意事项与最佳实践
通过以上方法,您即可稳定、可扩展地从动态网页中提取结构化联系信息,为后续 CRM 分析或外呼任务提供可靠数据支撑。










