尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
手机号归属地离线库:36万号段清洗入库与批量查询实战
简介全国手机号码段归属地数据库收录了360569条手机号码段记录以7.48MB的zip压缩包形式打包共4个文件包括SQL脚本、CSV数据表和两份txt说明文档。SQL脚本提供建表与插入语句可在MySQL等数据库内快速创建号码段表并按前7位号码查询归属地CSV文件可直接用Excel打开支持按号码段、运营商、省份、城市、区号、邮编等字段排序、过滤和透视。这份资源面向开发人员、数据分析师及运营人员适用于反欺诈风控、区域精准营销、客服本地化识别以及通信消费特征研究等场景。txt说明详细列出了字段含义与导入注意事项方便使用者理解数据结构省去自行采集、清洗和整理数据的繁琐步骤基于此可在业务系统中实现毫秒级号码归属查询或用于构建地域维度的用户画像。资源已有5054人学习下载质量经过充分验证是快速获取全国手机号码段归属地信息的实用数据集。1. 手机号归属地资源36万条离线数据先解决“号段能不能查准”做短信通道号段清洗时我吃过一次亏按手机号前三位判断归属地和运营商结果虚拟运营商号段和固网号段混在一起一次营销活动把错误归属地的用户全筛了进去。从那以后我坚持用离线号段归属地数据库做预处理而不是在线接口或随手抄来的号段表。这份资源是“全国手机号码段归属地数据库”Excel格式共360569条记录。给定一个手机号或其前7位号段能查到对应省份、城市、运营商。36万条记录覆盖绝大多数在网号段查询不依赖在线API没有频次和费用限制适合批量离线清洗。适合谁做短信外呼运营的按归属地分通道做风控反欺诈的甄别虚拟运营商号段做用户画像的给手机号打地域标签。只查一两个号请直接百度要查几万条时这份库的价值才体现出来。2. 号码段的内在结构11位怎么拆、字段粒度怎么定这步决定了查询快慢拿到手先别急着写SQL。手机号11位可以拆成三段前3位是网络识别号粗略对应运营商第4到第7位是HLR识别号归属地信息主要藏在这4位里后4位是用户随机号跟归属地无关。所以号码段归属地查询的真正匹配键是前7位不是前3位更不是完整11位。这也是为什么很多网上流传的“按前3位查归属地”工具不准——前3位只能区分运营商区分不了城市。2.1 先认清字段一份表里通常藏了四五个有效列我拿到这类资源后第一步不是写查询而是先用一个脚本把文件读一遍看表头和前几行数据。以这份库为例常见的字段组织方式是号段前缀、省份、城市、运营商偶尔还有一列“卡类型”比如区分普通卡、物联网卡。要特别说明一个坑网上流传的号段库版本非常多常见三种。一种是只有前7位号段和省市的精简表条目一般几万条一种是带完整11位号码明细的版本几十万条还有一种是加了虚拟运营商标记的扩展版。这份资源是360569条记录属于中等偏全的级别——既不是简陋的几万条前缀表也不是纯粹拿随机号凑数的明细表适合直接集成到业务库中当字典用。如果下载后打开发现表头和我说的不完全一样不用慌改一下脚本里的列名映射就行。关键列就四个号码前缀前7位、省份、城市、运营商。前7位缺失或格式不对这份数据基本没法用。2.2 数据校验先查文件完整性再按省份看分布确认字段后做两个快速校验文件是否完整、记录分布是否符合预期。一个36万行的文件如果来源不正规经常会有截断、空行、重复前缀问题。我用下面这段Python脚本做基础体检下载解压后可以直接跑import pandas as pd from collections import Counter # 读入数据sep按实际文件分隔符调整 df pd.read_csv(phone_location.csv, sep,, dtypestr, encodingutf-8) print(总记录数:, len(df)) print(空值统计:\n, df.isna().sum()) # 按前7位去重归属地查询的最小粒度 df[prefix7] df[phone].str[:7] unique_prefix df.drop_duplicates(subsetprefix7) print(去重后号段数:, len(unique_prefix)) # 按省份看记录分布检验是否覆盖全部省级行政区 prov_cnt Counter(unique_prefix[province]) print(省份数量:, len(prov_cnt)) for prov, cnt in prov_cnt.most_common(10): print(prov, cnt)这段脚本做的事情有四个第一行读入原始文件把手机号统一按字符串处理避免Excel自动转成科学计数法第二步输出总记录数和各列空值数量如果空值比例过高说明文件在传输过程中有损坏第三步把手机号截取前7位并去重得到真正的号段数目最后按省份统计看看是不是覆盖了全国所有省级行政区。参数说明读文件时dtypestr很关键手机号超过11位数字会被pandas默认当成数值类型前导0会被吞掉sep和encoding要根据实际拿到的文件调整常见的是逗号分隔加UTF-8也有用TAB分隔加GBK的。这一步做完基本就掌握了这份库的“边界”总共有多少个有效号段、哪些省份记录多、哪些省份记录少。比如虚拟运营商号段多的省份记录数会明显偏高这是号段分配所致不是数据错误。2.3 虚拟运营商号段这部分数据最容易出幺蛾子17开头的号段170、171、162、165、167等在归属地数据里经常“一人多身份”。原因很简单这些号段最初分配给某家基础运营商后来又转售给虚拟运营商经营导致同一号段在不同版本的数据库里归属信息不一致。我在实际项目中遇到过同一个170号段在这份库里显示是运营商A、某南方城市在另一份老库里却是运营商B、某北方城市。这种不一致不是数据“错”了而是号段转售时间点不同数据库快照时间不同。处理方式建议这样把170、171、162、165、167这类已知虚商号段单独拎出来建一张表不要混在主表里参与精确归属判断。主表用来查普通号段虚商表用来做二次甄别。两边的更新时间可以不同虚商表按季度维护就行。3. Excel落地实操CSV转码、去重、按省份拆表通讯录清洗直接抄3.1 打开前先处理编码中文乱码和行数截断两个老坑拿到Excel版的资源10个人里有4个直接双击打开然后遇到乱码或者只有65536行。先说乱码很多数据库导出文件是UTF-8无BOM编码Excel在中文Windows下默认按ANSIGBK打开中文就变乱码。我的处理方式先用Python把文件统一转成带BOM的UTF-8再双击打开。代码很短# 把无BOM的UTF-8文件转成带BOM解决Excel打开中文乱码 with open(phone_location.csv, rb) as f: raw f.read() # 如果文件头不是UTF-8 BOM就补上 if not raw.startswith(b\xef\xbb\xbf): with open(phone_location_bom.csv, wb) as f: f.write(b\xef\xbb\xbf raw) print(转换完成用Excel打开 phone_location_bom.csv)这段脚本只处理编码头不做其他改动。注意不要用记事本打开再另存为那会丢失原始编码信息还把36万行数据过一遍内存。再说行数截断旧版Excel2003及更早单个工作表最多65536行这份库36万条记录会被直接截掉大半。新版Excel虽然能打开上百万行但打开36万行本身就挺慢。我的建议是Excel只用来小范围抽查和人工核对真正批量查数放到数据库里做。3.2 数据清洗去重、截取前7位、统一运营商名称确认编码没问题后第一步是去重。资源包里的Excel不一定只有一个Sheet有的会按年份或来源分Sheet合并后重复号段很常见。我在Excel里处理时习惯这样操作在“手机号”列后插入辅助列输入LEFT(A2,7)截取前7位号段选中全部数据按“前7位号段”列排序用“数据—删除重复值”勾选号段列把重复号段删掉如果省份和城市是合并在一列比如“省份-城市”用“数据—分列”按分隔符拆开一个容易忽略的细节Excel的删除重复值是按整行比较的不是只按一列。如果两行号段相同但运营商字段略有差异它不会删。这种情况我一般保留第一条把运营商的差异丢到备注列里不阻塞主流程。清洗完记得再看一眼总行数。如果去重后从36万掉到不足20万说明原始文件里将近一半是重复记录这是正常的因为同一号段可能对应多个手机号明细如果掉到几万条说明这份文件本质是前7位号段表而非全量号码明细使用时要调整预期。3.3 按省份拆分成多个工作表一个VBA宏搞定通讯录清洗、按省份分渠道下发这类场景经常要把36万条记录按省份拆开。手工筛选复制太慢用VBA写个小宏Sub SplitByProvince() Dim src As Worksheet, dst As Worksheet Dim lastRow As Long, i As Long Dim prov As String Dim dstSheet As Worksheet Dim targetRow As Long Set src ThisWorkbook.Sheets(数据) lastRow src.Cells(src.Rows.Count, B).End(xlUp).Row 假设省份在B列 先删掉旧的拆分结果表 Application.DisplayAlerts False For Each dstSheet In ThisWorkbook.Worksheets If dstSheet.Name Like 省_* Then dstSheet.Delete Next Application.DisplayAlerts True For i 2 To lastRow 从第2行开始第1行是表头 prov src.Cells(i, B).Value If Trim(prov) Then Set dst Nothing On Error Resume Next Set dst ThisWorkbook.Worksheets(省_ prov) On Error GoTo 0 If dst Is Nothing Then Set dst ThisWorkbook.Worksheets.Add(After:ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count)) dst.Name 省_ prov src.Rows(1).Copy dst.Rows(1) 复制表头 End If targetRow dst.Cells(dst.Rows.Count, B).End(xlUp).Row 1 src.Rows(i).Copy dst.Rows(targetRow) End If Next i MsgBox 拆分完成 End Sub这段宏有几个参数要按实际情况改第一行“数据”是源Sheet名改成你实际的工作表名省份列是B列如果你的省份在C列把两处“B”改成“C”生成的拆分表统一带“省_”前缀方便识别。逻辑说明先获取源数据最后一行行号遍历每一行取出省份如果以“省_省份名”命名的工作表不存在就新建并复制表头存在就直接把整行复制过去。这里用On Error Resume Next而不是Exists检查是为了兼容旧版Excel没有Worksheet对象Exists方法的限制。拆分完成后强制做一次行数核对把拆分前总行数减1行表头和所有“省_*”表的行数求和对比不一致就说明宏里目标行定位有问题。我吃过这个亏——有一次漏了表头行拆分结果对所有数据都错位了一行前3万条用户归属地全部对错排查到天亮。如果你不想用VBA还有一个替代方案插入数据透视表把“省份”拖到筛选区域逐个筛选复制。数据量小无所谓36万行明显用宏更省事而且能重复跑。4. 把36万条记录推进MySQL建表、批量导入与三种查询场景4.1 建表varchar还是char字符集和索引怎么选不要直接用Excel当生产库。36万行放Excel里多人同时查卡死不说每次清洗都要全表加载。推进MySQL是标准做法。表结构建议这样建CREATE TABLE phone_location ( id INT NOT NULL AUTO_INCREMENT, prefix7 CHAR(7) NOT NULL COMMENT 手机号前7位, province VARCHAR(32) NOT NULL COMMENT 省份, city VARCHAR(32) NOT NULL COMMENT 城市, operator VARCHAR(32) NOT NULL COMMENT 运营商, source_tag VARCHAR(16) DEFAULT base COMMENT 数据来源标记, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_prefix (prefix7) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT手机号段归属地字典;几个选择理由prefix7用char(7)而不是varchar因为前7位长度固定char省去变长字段的额外开销等值查询更快省份城市运营商用varchar(32)长度收住防止脏数据写爆唯一索引uk_prefix直接保证同一号段只有一条数据重复导入时会报错而不是静默累积。最后加source_tag字段用来标记数据版本后面增量更新时有用。字符集必须utf8mb4不要用utf8。utf8在MySQL里是utf8mb3的别名遇到生僻字或emoji会报错或乱码省市区字段里偶尔会出现生僻地名别在这里省空间。导入前记得清理数据同一前7位有多条记录时uk_prefix会挡住导入。不要用INSERT IGNORE跳过错误否则看不出脏数据。正确做法是先按前缀去重合并再导入。4.2 批量导入LOAD DATA和Python两条路36万行说多不多说少不少。最快的是LOAD DATALOAD DATA LOCAL INFILE /data/phone_location.csv INTO TABLE phone_location CHARACTER SET utf8mb4 FIELDS TERMINATED BY , ENCLOSED BY LINES TERMINATED BY \n IGNORE 1 LINES (prefix7, province, city, operator) SET source_tag v2025;LOAD DATA是按“行”导入36万行通常几秒完成。如果中间报错说明CSV里有转义问题比如某个城市名里带了逗号没加引号。我一般会先用Python做一次校验再LOAD不然排查CSV的坑很费时间。如果你不熟LOAD DATA用Python pandas也够快from sqlalchemy import create_engine import pandas as pd df pd.read_csv(phone_location.csv, dtypestr) # 同一个前缀只保留第一条归属信息 df df.drop_duplicates(subsetprefix7, keepfirst) df[source_tag] v2025 engine create_engine(mysqlpymysql://user:passlocalhost/phone_db?charsetutf8mb4) df.to_sql(phone_location, engine, if_existsappend, indexFalse, chunksize5000)这段代码里chunksize5000表示每5000条提交一次避免一次性提交36万行把内存撑爆。if_existsappend是追加模式适合增量更新第一次跑建议用replace或先把表DROP掉再建。导入完查一下总数SELECT COUNT(*), COUNT(DISTINCT prefix7) FROM phone_location;如果两个数相同说明没有重复号段如果差异很大回去看看Excel里是否有同一号段多条记录没合并干净。4.3 三种查询场景单号、批量IN、联表清洗查单号归属地SELECT province, city, operator FROM phone_location WHERE prefix7 LEFT(13900000001, 7);注意这里不是直接写死前7位而是用LEFT函数统一截取避免查询时手算出错。这个写法在存储过程或视图里用很稳。批量查几万个号-- 假设有一张待清洗表 temp_phones(phone VARCHAR(11)) SELECT p.phone, t.province, t.city, t.operator FROM temp_phones p LEFT JOIN phone_location t ON t.prefix7 LEFT(p.phone, 7);LEFT JOIN而不是INNER JOIN是为了把没匹配到的号码也带出来方便看哪部分号码是库里没有的新号段。新号段的比例能告诉你这份库是不是该更新了。匹配不上时按号段年龄段看未命中分布SELECT LEFT(phone, 3) AS seg3, COUNT(*) AS miss_cnt FROM temp_phones p LEFT JOIN phone_location t ON t.prefix7 LEFT(p.phone, 7) WHERE t.prefix7 IS NULL GROUP BY LEFT(phone, 3) ORDER BY miss_cnt DESC;如果未命中集中在19x和20x开头的号段基本可以判断是新放号的号段还没收录如果未命中是随机分布先检查手机号列有没有混入固话或非法字符。4.4 两种常见误用前3位分组和LIKE模糊查询最容易翻车的是这两类写法-- 错误写法1只用前3位当归属地 SELECT LEFT(phone,3), COUNT(*) FROM temp_phones GROUP BY LEFT(phone,3); -- 错误写法2全字段模糊匹配 SELECT * FROM phone_location WHERE prefix7 LIKE %139%;第一种不是查归属地是查运营商第二种LIKE %139%会放弃uk_prefix索引36万行全表扫描慢不说还容易匹配到错误行。统计运营商分布可以用前3位但要查省市必须用前7位这是原则。如果业务上非要支持前缀模糊查询给prefix7保留普通索引并且用“prefix7 LIKE 139%”这种前缀匹配索引才用得上。36万行上没有性能压力但写法从一开始就要正确否则换个百万级表直接卡死。5. 避坑指南归属地数据使用中常见的五个翻车现场用这类数据一年半载踩过的坑值得记下来。每一条我都标注了现象、原因和解决方式按优先级排的。5.1 虚拟运营商号段“一查两归属”现象查170号段有时候返回运营商A某南方城市有时候返回运营商B某华东城市。同一批数据两条记录都对不上。原因虚商号段是基础运营商划转给虚拟运营商经营的号段资源登记表在不同时间点生成了不同快照。这份库如果混用了两个版本的数据就会同时存在两条归属记录。解决把17开头170/171/162/165/167等号段单独拆出来建一张虚商号段表。日常查询默认用主表只有主表未命中时才查虚商表两张表各自维护更新时间不要强行合并成一张。5.2 携号转网让运营商字段“过期”现象某号码在库里的运营商标记是A实际用户半年前转到了B。短信通道按运营商路由时大批量短信被退回。原因归属地数据库的运营商字段是从发卡时刻记录的携号转网后不会自动回写。这类离线库天然滞后于实时网络状态。解决原则上把“运营商”当参考字段不做强路由依据。运营商强敏感场景用运营商侧接口单独核验或定期把转网用户名单拉回来在库里打标。归属地省、市不受携号转网影响可以放心用。5.3 36万行在旧版Excel里只剩65536行现象双击打开文件拉到最下面只有65536行另一半数据不知所踪。原因旧版Excel2003及更早单工作表行数上限就是65536超过的写不进工作表。新版Excel虽然支持104万行但打开时如果文件是xls老格式同样可能触发兼容模式截断。解决确认文件版本不要用第三方小工具强行转格式。建议只用Excel做抽查和人工核对整库查询放到MySQL或SQLite里。如果你是拿Excel直接跑VLOOKUP做清洗36万行的VLOOKUP本身就是性能灾难等它算完不如喝杯咖啡。5.4 CSV导入Excel后中文乱码现象导入CSV后省份和城市全是“鍖椾含”“娴峰崡”这类乱码。原因文件是UTF-8无BOM编码Excel按本机ANSI代码页解析字节流错位了。这个不是数据损坏是编码声明缺失。解决按第3章的方法把文件转成带BOM的UTF-8或直接存成GBK。转码脚本5分钟搞定不值得在这个问题上浪费时间。转完之后抽查几个省份词比如“某省”“某市”确认没有乱码再往下走。5.5 把归属地当实时位置风控误杀一片现象某用户注册地在某北方城市出差到南方某市后登录风控系统按号码归属地判断“异地登录”直接触发限制用户投诉到客服。原因号码归属地等于发卡地不等于当前所在城市。这张表的“城市”是办卡时登记的归属地和基站的实时位置完全是两回事。解决归属地只用来做离线画像比如沉默用户的地域分布、注册地分析、短信分省下发实时风控用授权定位或基站信令不要把归属地当成LBS字段参与实时决策。哪个维度用哪个数据一开始就要在表设计上分开。6. 进阶校验一个批量自检脚本和增量更新策略6.1 一个可复用的自检脚本每拿一批新手机号先跑一遍自检脚本再决定是否进清洗流程import re import sqlite3 conn sqlite3.connect(phone_location.db) phones [13900000001, 17012345678, 12345, 15800000123] for p in phones: if not re.fullmatch(r1[3-9]\d{9}, p): print(p, 格式不合法) continue row conn.execute( SELECT province, city, operator FROM phone_location WHERE prefix7?, (p[:7],) ).fetchone() if row: print(p, row) else: print(p, 未命中号段需检查是否为新号段)正则只做最基础的格式校验不判断号段是否真实分配。匹配不上时先确认是不是新号段而不是直接打日志忽略。6.2 增量更新的维护习惯离线归属地库的保质期大概在半年到一年。每月对照主管部门的新号段公告把新增前7位合并进主表。建议每次更新带版本号旧文件按日期归档不要覆盖。有一次我图省事直接覆盖导入结果新库和旧库混在一起查出来的归属地各说各话花了一下午才把数据恢复回来。从那以后我每次更新都强制走三件事备份旧文件、跑一遍自检脚本、核对新增号段数量。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

外贸独立站如何选SEO服务商?避坑指南

外贸独立站如何选SEO服务商?避坑指南

外贸独立站卖家挑选 SEO 服务商,很容易被漂亮的案例截图、营销话术迷惑。判断服务商靠谱与否,不能只看宣传,需要一套可落地的核验标准,从承诺、执行人、案例、技术手法、交付逻辑、资产权限多个维度综合甄别。1. 看承诺&#xff1…

📅 2026/10/14 7:40:16
Boost.Asio tcp::iostream:用C++流式编程简化TCP网络通信

Boost.Asio tcp::iostream:用C++流式编程简化TCP网络通信

1. 核心机制与关键细节拆解1.1 为什么能用“流”来跑网络数据先聊一个很多新手第一次看到boost::asio::ip::tcp::iostream时的疑惑:网络传输明明是基于字节流的收发动作,怎么会和一个操作本地文件的“流”扯上关系?其实这个设计思路的本质&am…

📅 2026/10/14 7:35:16
Boost.Asio tcp::iostream:用C++流式IO简化TCP网络编程

Boost.Asio tcp::iostream:用C++流式IO简化TCP网络编程

Boost.Asio的ip::tcp::iostream是我用过的最让人舒服的网络编程接口之一。如果你写过原始socket,一定受够了bind、listen、accept、send、recv这一整套流程,再加上错误码处理、缓冲区管理、字节序转换,光是搭一个能跑的TCP客户端就要几十行。…

📅 2026/10/14 7:35:16
MORE NEWS

更多资讯

📰

Qt QSlider自定义:带气泡游标的滑块实现与避坑指南

简介:针对标准QSlider无法在滑块正上方显示当前值的痛点,这份资源提供了一套基于Qt的自定义滑块实现方案,适合需要实时数值反馈的桌面应用开发者参考。资源包含完整可运行的testSlider工程,通过继承QSlider并重写paintEvent()绘制…

📰

LiteLLM:统一大模型API网关的落地实践与避坑指南

你手里攒了两三个大模型 API 的体验账号,想在同一个系统里随意切换“大模型服务商”,大概率会先被各家接口的差异搞到怀疑人生。LiteLLM 就是专门解决这个问题的轻量级开源网关:它把市面上常见模型服务商全部收敛成统一的接口格式&#xff0c…

📰

Litellm 网关层详解:统一 OpenAI、Claude、Gemini 等模型接口

Litellm 这个名字,我建议所有做 AI 应用的后端开发都先记下来。它不是一个"AI 神器"或者花哨的提示词工具,而是一个被很多团队实打实用了很久的 LLM 网关层。一句话概括:它把 OpenAI、Anthropic、Google、Azure,以及各类…

📰

COMSOL中弯月型结构BIC仿真与斜入射线偏振设置

1. 弯月型结构BIC仿真概述在光学仿真领域,边界条件设置一直是决定仿真精度的关键因素。最近我在研究COMSOL中弯月型结构的束缚态连续体(BIC)仿真时,发现斜入射线偏振光的边界条件设置存在不少技术细节需要特别注意。这种特殊结构在光子晶体、超表面等领域…

📰

MFC窗口分割实战:CSplitterWnd静态与动态分割及嵌套布局详解

1. 从一个实际需求说起:为什么要做窗口分割 做过桌面软件的人大概都有过这种体验:主界面里既要放一个树形导航,又要在右边显示详细内容,还得在底部留一块区域输出日志或者状态信息。如果把这些控件全塞进一个视图里,代…

📰

微信小程序字符串处理全攻略:split/substring/concat/charAt实战

做小程序开发这两年多,我最大的感受就是:字符串处理其实占了日常逻辑的三成以上。不管是接口返回的数据格式整理、用户输入的表单校验,还是列表渲染前的加工,翻来覆去就是那些方法——split切割、substring提取、concat拼接、char…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬