广电开始有电信业务了,号码归属地表又是一顿更新,如果跟不上步伐可能会引发一些事故。目前暂时本人暂时无法做到自己去爬数据,所以就只能借助网上大佬的数据库来使用了。
找了一圈,找到了lovedboy大佬的github库。以及相对应的脚本。原本的使用方法应该是数据文件+脚本形成可以即时调用的方法,但无奈自家是写进mysql的,只能无奈将其导出。
修改了大佬的原调用脚本,测试失败。😅
索性摆烂,将大佬脚本和需求丢进chatgpt跑一圈,出来以下脚本,试运行,丝滑。😲
放出来给大家看看。
# -*- coding: utf-8 -*-
import os
import struct
import sys
__author__ = 'lovedboy'
if sys.version_info > (3, 0):
def get_record_content(buf, start_offset):
end_offset = buf.find(b'\x00', start_offset)
return buf[start_offset:end_offset].decode()
else:
def get_record_content(buf, start_offset):
end_offset = buf.find('\x00', start_offset)
return buf[start_offset:end_offset]
class Phone(object):
def __init__(self, dat_file=None):
if dat_file is None:
dat_file = os.path.join(os.path.dirname(__file__), "phone.dat")
with open(dat_file, 'rb') as f:
self.buf = f.read()
self.head_fmt = "<4si"
self.phone_fmt = "<iiB"
self.head_fmt_length = struct.calcsize(self.head_fmt)
self.phone_fmt_length = struct.calcsize(self.phone_fmt)
self.version, self.first_phone_record_offset = struct.unpack(
self.head_fmt, self.buf[:self.head_fmt_length])
self.phone_record_count = (len(self.buf) - self.first_phone_record_offset) // self.phone_fmt_length
def get_phone_dat_msg(self):
print("版本号:{}".format(self.version))
print("总记录条数:{}".format(self.phone_record_count))
@staticmethod
def get_phone_no_type(no):
if no == 4:
return "电信虚拟运营商"
if no == 5:
return "联通虚拟运营商"
if no == 6:
return "移动虚拟运营商"
if no == 3:
return "电信"
if no == 2:
return "联通"
if no == 1:
return "移动"
@staticmethod
def _format_phone_content(phone_num, record_content, phone_type):
province, city, zip_code, area_code = record_content.split('|')
return {
"phone": phone_num,
"province": province,
"city": city,
"zip_code": zip_code,
"area_code": area_code,
"phone_type": Phone.get_phone_no_type(phone_type)
}
def _parse_record(self, record):
phone_num, record_offset, phone_type = struct.unpack(self.phone_fmt, record)
record_content = get_record_content(self.buf, record_offset)
return Phone._format_phone_content(phone_num, record_content, phone_type)
def all(self):
records = []
buflen = len(self.buf)
for i in range(self.first_phone_record_offset, buflen, self.phone_fmt_length):
record = self.buf[i: i + self.phone_fmt_length]
records.append(self._parse_record(record))
return records
def test(self):
self.get_phone_dat_msg()
records = self.all()
for record in records:
print(self.human_phone_info(record))
@staticmethod
def human_phone_info(phone_info):
if not phone_info:
return ''
return "{}|{}|{}|{}|{}|{}".format(phone_info['phone'],
phone_info['province'],
phone_info['city'],
phone_info['zip_code'],
phone_info['area_code'],
phone_info['phone_type'])
if __name__ == "__main__":
phone = Phone()
phone.test()
Read More ~
标签:#
python
号码归属地库
号码归属地库
数据库的号码归属地是18年之前的,因为出现很多号码新号码不识是的问题,所以需要更新一遍。
在此之前我想了下流程,主要是分以下几步。
获取号码和区域代码(区号)
制作区号代码字典(区号,省份,城市)
根据区号补充号码的省份和城市(号码,区号,身份,城市)
拼接插库语句
获取号码和区域代码
这里我采用很久之前看到的GitHub上一位大佬的库,使用PHP拉取3大运营商的号码和区号,我直接取用大佬拉好的数据。
[url]: https://github.com/chenxinbin/china-mobile-location
#数据格式如下
1330010 010
1330011 010
1330018 021
制作区号代码字典
根据我从之前数据库拉出来的区号信息制作字典。
数据格式如下,并保存至txt文本中
00852 香港 香港
010 北京 北京
020 广东 广州
具体方法如下,让python逐行读取文本内容,分割文本之后存入list,然后再依次存入两个字典中。
#初始化参数
province = {} #创建空字典省份
city = {} #创建空字典城市
a_dist = open('./dist.txt', 'r', encoding='UTF-8') #读取文件,使用utf-8格式使用
#读取,分割,制作字典
for line in a_dist:
lines = line.replace('\n', '') #可能存在换行符,影响结果,这里置换为空
split = lines.split('\t') #以制表符为分割点,分割
province[split[0]] = split[1] #添加区号查询的省份字典
city[split[0]] = split[2] #添加区号查询的城市字典
a_dist.close()
根据区号补充号码的省份和城市
根据上面两个步骤得出的数据可以生成一份,号码-区号-省份-城市 的对应数据。
a_10000 = ('./10000.txt', 'r', encoding='UTF-8')
for number in a_10000:
lines = line.replace('\n', '')
split = lines.split(' ') #同理可得对应list
#写入txt文件
try:
w_txt = open('./dianxin.sql', 'a', encoding='UTF-8') # 'a' 为追加模式,请确保文本为空
w_txt.write('号码:%s,区号:%s,省份:%s,城市:%s' % (split[0], split[1], province[split[1]], city[a[1]]))
excrpt:
print(split[0]) #打印号码
print(split[1]) #打印区号
f_name.close()
拼接插库语句
根据写入文件的方法自行修改
a_10000 = ('./10000.sql', 'r', encoding='UTF-8')
for number in a_10000:
lines = line.replace('\n', '')
split = lines.split(' ') #同理可得对应list
#写入txt文件
try:
w_txt = open('./dianxin.sql', 'a', encoding='UTF-8') # 'a' 为追加模式,请确保文本为空
w_txt.write('INSERT into splitresplitNumber (Number,splitresplitNumber,Province,City) VsplitLUES (\'%s\',\'%s\',\'%s\',\'%s\');\n' % (split[0], split[1], province[split[1]], city[split[1]]))
excrpt:
print(split[0]) #打印号码
print(split[1]) #打印区号
f_name.close()
接着执行sql文件,就能愉快的添加了。
原创文章转载请留言
初学方法,比较费时费力。欢迎吐槽~
Read More ~