lex数软工作室

长期承接软件开发,数据采集,图像处理,技术咨询 微信:lex_workshop

使用python接收本地手机号短信

如果需要长期接受短信,进行业务,可使用如下方案

设计流程如下:

购买相应的usb接收短信的硬件设备

我使用的是EC600N 4G USB口模块,各位请自行在淘宝里面购买,此设备为4G三网通设备

python相应代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#短信
import serial,time,hashlib
import binascii
import re


def hexToStr(hexStr:str):
hex = hexStr.encode('utf-8')
str_bin = binascii.unhexlify(hex)
return repr(str_bin.decode('utf-8')).replace('\\x00','').replace("'","")

def unicodeToStr(unicodeStr:str):
res=[]
for i in range(0,len(unicodeStr),4):
res.append(r'\u'+unicodeStr[i:i+4])
return ''.join(res).encode().decode("unicode_escape")

def strToUnicode(msg:str):
res=[]
for item in msg:
try:
res.append(hex(ord(item.encode('unicode_escape'))).lower().replace('0x','00'))
except:
res.append(repr(item.encode('unicode_escape')).replace("b'\\\\u",'').replace("'",''))
print(''.join(res))
return ''.join(res)

class Ec600:
def __init__(self,port='COM11',baudrate=115200):
self.ser=serial.Serial(port, baudrate, timeout=1)
while not self.ser.is_open:time.sleep(0.1)
time.sleep(1)
print('识别成功')

def readMSM(self):
'''
读取短息
'''
self._sendMsg("AT\r\n")
print(' '.join(self._readMsg()))
self._sendMsg("at+cmgf=1\r\n")
print(' '.join(self._readMsg()))
self._sendMsg("AT+CMGL=\"ALL\"\r\n")
#self._sendMsg("AT+CMGL=\"REC UNREAD\"\r\n")
msgs=self._excuteMSM(' '.join(self._readMsg()))
results=[]
localNum=self.getPhoneNum()
for line in msgs:
phoneNum,receiveTime,msg=self.extractInformation(line)
results.append((phoneNum,receiveTime,msg,localNum))
return results

def extractInformation(self,line):
phoneNum = re.findall('(?<=READ",").+?(?=")', line)[0].replace('003','')
creatTime = re.findall('\d{2}/\d{2}/\d{2},\d{2}:\d{2}:\d{2}.\d{2}', line)[0][:17]
try:
msg = unicodeToStr(re.findall('''(?<="\d{2}/\d{2}/\d{2},\d{2}:\d{2}:\d{2}.\d{2}" )[0-9A-F]+''', line)[0])
except:
msg = ''
return phoneNum,creatTime,msg

def deleteMSM(self):
'''
删除已读短信
:return:
'''
print('删除短息')
self._sendMsg("AT\r\n")
print(' '.join(self._readMsg()))
self._sendMsg("at+cmgf=1\r\n")
print(' '.join(self._readMsg()))
self._sendMsg("AT+CMGD=1,2\r\n")
print(' '.join(self._readMsg()))

def _readMsg(self) -> list:
if self.ser.readable():
res=[]
for line in self.ser.readlines():
msg=line.decode().replace("\r","").replace("\n","")
if len(msg)>0:
res.append(msg)
return res
return []

def _sendMsg(self,code:str):
self.ser.write(code.encode())

def _excuteMSM(self,msm:str):
res = re.findall('''.CMGL.+?"\\d+/\\d+/\\d+,\\d+:\\d+:\\d+.\\d+" [0-9A-F]+''', msm)
return res

def sendMsg(self,phoneNum,msg:str):
# 设置短信模式为PDU
self._sendMsg("AT\r\n")
self._sendMsg('AT+CMGF=1\r\n')
self._sendMsg('AT+CSMP=17,167,2,25\r\n')
# 设置短信编码
self._sendMsg('AT+CSCS="UCS2"\r\n')
# 手机号码 16进制unicode码
self._sendMsg('AT+CMGS="'+self._turnPhoneNum(phoneNum)+'"\r\n')
# 短信内容 16进制unicode码
print(' '.join(self._readMsg()))
self._sendMsg(strToUnicode(msg))
# 发送代码
self._sendMsg('\x1A\r\n')
print(' '.join(self._readMsg()))

def _turnPhoneNum(self,phoneNum:str):
res=[]
for i in phoneNum:
res.append('003'+i)
print(''.join(res))
return ''.join(res)

def getPhoneNum(self):
'''
获得手机号
'''
self._sendMsg("AT\r\n")
print(' '.join(self._readMsg()))
self._sendMsg("AT+CNUM\r\n")
phoneStr=' '.join(self._readMsg())
return re.findall('(?<=\+86)[0-9]{11}',phoneStr)[0]

使用上诉代码,win上查看com号,linux上查看dev/tty号,设置Ec600的port参数,调用相应方法即可读取短信

⬅️ Go back