手机归属地查询步伐

从几个手机号码归属地的查询,到几千手机号码的查询,最后到百万级别以上的手机号码归属地查询。有时为了分析数据的真伪,渠道质量的好坏,或者是分析诈骗手机号码的来源(扯远了)都会时不时的会查找下手机归属地。
1、几个手机号码的归属地查询就采用纯手动的方式,用百度、谷歌(科学上网需要翻墙)找几个可以提供手机号码归属地查询的WEB页面就可以了。

2、几千的手机号码采用手动输入的方式的话,那肯定是太傻了。可以利用网上提供的开发API接口结合脚本查询,这篇blog中提供了常用的开发API:http://blog.sina.com.cn/s/blog_7bac4707010143o2.html
其中感觉淘宝的那个比较好用,不过都有弊端那就是请求的次数过于频繁的时候会要求输入验证码什么的,防止过于频繁的请求(估计可能是防DDOS攻击吧)。不过几千左右的查询问题不大,对于这种情况可以尝试请求多个不同的API接口,一个不行接着请求下一个,下一个不行再请求下一个。
下面是我曾经用过的一个脚本,总共用到了3个不同的API接口,文件phone.list是保存的手机号码,result.tmp是保存查询结果的文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
phoneNum='./phone.list'
rm -f result.tmp
for num in `cat $phoneNum`
do
url='http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel='$num
res=`curl $url --silent | grep "province:" | awk -F"'" '{print $2}'`
if [ -z $res ];
then
url='http://life.tenpay.com/cgi-bin/mobile/MobileQueryAttribution.cgi?chgmobile='$num
res=`curl $url --silent |awk -F '<city>' '{print $2}'|awk -F '</city>' '{print $1}'`
fi

if [ -z $res ];
then
url='http://www.096.me/api.php?mode=xml&phone='$num
res=`curl $url --silent |awk -F '<location>' '{print $2}'|awk -F '</location>' '{print $1}'`
fi

if [ -n $res ];
then
echo "$num $res" >> result.tmp
fi
done

手机号码一行一条,类似这样

1
2
3
4
188xxxxx128
135xxxxx627
136xxxxx642
185xxxxx628

3、当手机号码在百万级别的时候,如果采用上面第二种方式肯定是行不通的了(如果允许足够的查询时间比如2天,可以使用)。我试过采用请求公网开发的API接口,10个小时大概可以跑10万左右的数据.其中很多时间是浪费在选择当前可用的API接口的过程中(当一个接口访问频率过高时会暂时屏蔽你的IP访问),当然还有网络传输数据时间的浪费。
这种情况最好就是在本地有个可靠的手机归属地的数据库,这篇blog的博主提供了靠谱的数据库并且还带采集更新程序:http://duanmu.org/log/mobile/
将提供的31万个号段的access数据导入到数据库后就可以开工了,我采用的是mysql数据库。查询脚本如下:

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
#coding=utf-8
#!/user/bin/env python2.6
import MySQLdb

def get_addr():
outfp = open('result.tmp', 'w')
infp = open('phone.list','r')
conn=MySQLdb.connect(host='127.0.0.1',user='root',passwd='password',db='phone',port=3306,charset="utf8")
cursor = conn.cursor()
for phone in infp:
phone = phone.replace('\r\n', '')
phone = phone.replace('\n', '')
ph = phone[0:7]
sql_cmd = 'select mobilearea from dm_mobile where mobilenumber='+ph;
cursor.execute(sql_cmd)
for row in cursor.fetchall():
local = row[0].replace(' ','')
if local:
outfp.write(local.encode('utf8'))
outfp.write("\n")
else:
outfp.write(phone)
outfp.write("\n")
conn.close()
outfp.close()
infp.close()

get_addr()

用该脚本查询百万级别的手机号码,只要1分钟左右,是不是比几天快多了,需要注意的是为了保持快速高效的查询需要给表的mobilenumber(号码)字段加索引。

----------------本文结束 感谢阅读----------------