你能想象吗?只需一段 Python 代码,就能让你的小米手机像训练有素的接线员一样,自动拨打上百个电话号码,全程无需人工干预!本文将揭秘如何用技术打造属于你的 "自动化呼叫中心",彻底解放你的双手!
核心功能展示
先看看我们将实现的核心功能:
- 从 Excel/CSV 批量导入电话号码
- 自动拨号并监控通话状态
- 智能识别接通 / 未接状态
- 通话时长自动记录
- 异常情况自动重试
- 完整的通话日志记录
下面是完整的实现代码:
python
运行
import subprocess
import re
import time
import os
import pandas as pd
from datetime import datetime
from find_adb import *
# 配置参数
PHONE_NUMBER_FILE = 'phone_numbers.csv' # 电话号码文件
STATE_FILE = 'settings/phone_state.txt' # 状态文件
LOG_FILE = 'call_logs.csv' # 通话日志文件
DIAL_INTERVAL = 10 # 拨号间隔(秒)
RETRY_TIMES = 3 # 重试次数
adb_path = get_adb_path()
# 电话状态枚举
PHONE_STATES = {
'IDLE': '空闲',
'DIALING': '拨号中',
'ALERTING': '响铃中',
'ACTIVE': '通话中',
'DISCONNECTING': '挂断中',
'DISCONNECTED': '已挂断'
}
def get_current_phone_state():
"""获取当前电话状态"""
try:
with open(STATE_FILE, 'r') as f:
return f.read().strip()
except FileNotFoundError:
return "UNKNOWN"
def write_state(state):
"""写入当前电话状态"""
with open(STATE_FILE, 'w') as f:
f.write(state)
def execute_adb_command(command):
"""执行ADB命令"""
try:
process = subprocess.run(
[os.path.join(adb_path, "adb.exe")] + command,
capture_output=True,
text=True,
check=True
)
return process.stdout.strip()
except subprocess.CalledProcessError as e:
print(f"ADB命令执行失败: {e.stderr}")
return None
def connect_device():
"""连接安卓设备"""
print("正在连接安卓设备...")
devices = execute_adb_command(["devices"])
if not devices or "device" not in devices:
print("未检测到已连接的安卓设备!")
return False
print("设备连接成功!")
return True
def dial_phone_number(phone_number):
"""拨打电话"""
print(f"正在拨打: {phone_number}")
execute_adb_command(["shell", f"am start -a android.intent.action.CALL -d tel:{phone_number}"])
time.sleep(2) # 等待拨号界面加载
def hangup_call():
"""挂断电话"""
print("正在挂断电话...")
execute_adb_command(["shell", "input keyevent KEYCODE_ENDCALL"])
time.sleep(2) # 等待挂断操作完成
def monitor_call_status(timeout=60):
"""监控通话状态变化,返回最终状态和通话时长"""
start_time = time.time()
call_start_time = 0
last_state = get_current_phone_state()
while time.time() - start_time < timeout:
current_state = get_current_phone_state()
# 状态变化时输出信息
if current_state != last_state:
print(f"状态变更: {PHONE_STATES.get(last_state, last_state)} -> {PHONE_STATES.get(current_state, current_state)}")
last_state = current_state
# 记录通话开始时间
if current_state == 'ACTIVE':
call_start_time = time.time()
# 通话结束,返回结果
if current_state == 'DISCONNECTED':
call_duration = 0
if call_start_time > 0:
call_duration = time.time() - call_start_time
return "COMPLETED", call_duration
time.sleep(1)
# 超时处理
if last_state == 'ACTIVE':
hangup_call()
return "MANUAL_HANGUP", time.time() - call_start_time
else:
hangup_call()
return "TIMEOUT", 0
def read_phone_numbers(file_path):
"""从文件读取电话号码列表"""
try:
if file_path.endswith('.csv'):
df = pd.read_csv(file_path)
elif file_path.endswith(('.xlsx', '.xls')):
df = pd.read_excel(file_path)
else:
raise ValueError("不支持的文件格式")
# 查找包含电话号码的列
phone_column = None
for col in df.columns:
if '电话' in col or '号码' in col or 'phone' in col.lower():
phone_column = col
break
if not phone_column:
raise ValueError("文件中未找到电话号码列")
return df[phone_column].dropna().astype(str).tolist()
except Exception as e:
print(f"读取电话号码文件失败: {e}")
return []
def log_call_result(phone_number, result, duration, retry=0):
"""记录通话结果"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
duration_str = f"{duration:.1f}秒" if duration > 0 else "0秒"
# 写入日志文件
file_exists = os.path.exists(LOG_FILE)
with open(LOG_FILE, 'a', encoding='utf-8') as f:
if not file_exists:
f.write("时间戳,电话号码,通话结果,通话时长,重试次数\n")
f.write(f"{timestamp},{phone_number},{result},{duration_str},{retry}\n")
# 控制台输出
print(f"📝 通话记录: {phone_number} - {result} - {duration_str} - 重试次数: {retry}")
def batch_dial_phones():
"""批量拨打电话主函数"""
if not connect_device():
return
phone_numbers = read_phone_numbers(PHONE_NUMBER_FILE)
if not phone_numbers:
print("没有可拨打的电话号码!")
return
print(f"共加载了 {len(phone_numbers)} 个电话号码")
total = len(phone_numbers)
for i, phone_number in enumerate(phone_numbers, 1):
print(f"\n===== 正在处理第 {i}/{total} 个号码: {phone_number} =====")
for retry in range(RETRY_TIMES):
print(f"尝试拨号 (重试次数: {retry})")
# 重置状态
write_state('IDLE')
# 拨号
dial_phone_number(phone_number)
# 监控通话状态
result, duration = monitor_call_status(timeout=120)
# 记录结果
log_call_result(phone_number, result, duration, retry)
# 判断是否需要重试
if result == "COMPLETED":
break
# 重试间隔
if retry < RETRY_TIMES - 1:
print(f"拨号失败,{DIAL_INTERVAL}秒后重试...")
time.sleep(DIAL_INTERVAL)
# 拨号间隔
print(f"等待 {DIAL_INTERVAL} 秒后继续下一个号码...")
time.sleep(DIAL_INTERVAL)
print("\n🎉 批量拨号任务已完成!")
if __name__ == "__main__":
batch_dial_phones()
工作流程详解
我们的批量拨号系统主要包含以下几个核心模块:
1. ADB 通信层
负责与小米手机建立连接并发送控制命令:
python
运行
def execute_adb_command(command):
"""执行ADB命令"""
try:
process = subprocess.run(
[os.path.join(adb_path, "adb.exe")] + command,
capture_output=True,
text=True,
check=True
)
return process.stdout.strip()
except subprocess.CalledProcessError as e:
print(f"ADB命令执行失败: {e.stderr}")
return None
2. 通话状态监控
实时捕获并解析手机通话状态:
python
运行
def monitor_call_status(timeout=60):
"""监控通话状态变化,返回最终状态和通话时长"""
start_time = time.time()
call_start_time = 0
last_state = get_current_phone_state()
while time.time() - start_time < timeout:
current_state = get_current_phone_state()
# 状态变化时输出信息
if current_state != last_state:
print(f"状态变更: {PHONE_STATES.get(last_state, last_state)} -> {PHONE_STATES.get(current_state, current_state)}")
last_state = current_state
# 记录通话开始时间
if current_state == 'ACTIVE':
call_start_time = time.time()
# 通话结束,返回结果
if current_state == 'DISCONNECTED':
call_duration = 0
if call_start_time > 0:
call_duration = time.time() - call_start_time
return "COMPLETED", call_duration
time.sleep(1)
# 超时处理
if last_state == 'ACTIVE':
hangup_call()
return "MANUAL_HANGUP", time.time() - call_start_time
else:
hangup_call()
return "TIMEOUT", 0
3. 批量处理引擎
管理整个批量拨号流程:
python
运行
def batch_dial_phones():
"""批量拨打电话主函数"""
if not connect_device():
return
phone_numbers = read_phone_numbers(PHONE_NUMBER_FILE)
if not phone_numbers:
print("没有可拨打的电话号码!")
return
print(f"共加载了 {len(phone_numbers)} 个电话号码")
total = len(phone_numbers)
for i, phone_number in enumerate(phone_numbers, 1):
print(f"\n===== 正在处理第 {i}/{total} 个号码: {phone_number} =====")
for retry in range(RETRY_TIMES):
# 拨号逻辑...
# 拨号间隔
print(f"等待 {DIAL_INTERVAL} 秒后继续下一个号码...")
time.sleep(DIAL_INTERVAL)
print("\n🎉 批量拨号任务已完成!")
实战应用场景
这套系统可以在以下场景中大显身手:
-
客户回访:客服团队可以使用该系统自动拨打客户电话,记录通话情况
-
电话营销:营销人员可以批量拨打潜在客户,提高工作效率
-
通知提醒:学校、医院等机构可以自动拨打通知电话
-
测试验证:开发人员可以用它测试电话相关的功能
如何使用
-
准备工作:
- 安装 ADB 工具并配置环境变量
- 启用小米手机的 USB 调试模式
- 安装必要的 Python 库:
pip install pandas
-
准备电话号码文件:
创建一个 CSV 或 Excel 文件,包含电话号码列 -
运行程序:
python batch_dialer.py
高级扩展
想要更强大的功能?可以考虑这些扩展方向:
- 添加语音识别,自动记录通话内容
- 集成 AI 对话机器人,实现智能语音交互
- 开发 Web 界面,实现远程控制和监控
- 添加短信自动回复功能
- 实现基于地理位置的智能拨号
有了这个 Python 批量拨号系统,你就拥有了一个 24 小时不停歇的 "数字接线员",让繁琐的拨打电话工作成为历史!还等什么?马上动手实现,释放你的生产力吧!