爬取手机号码归属地

去年年底,公司需要建个本地的手机号码归属地库,因为有点时间,又爱好python,就主动说来搞定这个。活接下来了,那么怎么实施呢?分为四步:

  1. 所有手机号码的获取
  2. 归属地的查询来源
  3. 请求数据的组装,返回数据的解析
  4. 有用数据的落地

一:号码的获取

国内手机号码十亿级别的,茫茫多的号码,一个一个获取肯定是不现实的,想想数据表得多大?
那怎么办呢?通过百度百科确认,要查归属地,只要根据前七位就ok了。那么数据只要 ‘151 5220 XXXX’这样就可以了,这样数据量可以压缩一万倍!然后搜索到目前国内三大运营商下面的手机号段分别有:

电信:
133、153、180、181、189、177、173、149
联通:
130、131、132、155、156、145、185、186、176、175
移动:
1340-1348、135、136、137、138、139、150、151、152、157、158、159、182、183、184、187、188、147、178

共37个号码段。所以我们只要37万条数据就ok了,而不是37亿条!

二:归属地的查询来源

国内靠谱点的手机号码归属地查询网站是?
国内主要的有ip138,114百事通,手机在线等,有些是收费的,有些返回整个html,综合下来:
适合我的是手机在线v.shouji.com,可免费且返回数据量很小!

三:请求数据的组装,返回数据的解析

然后在该网站上输入手机号码查询归属地,并开启charles抓包。


手机在线查询结果.png
Request.png
Response.png

通过抓包分析,请求为:

http://v.showji.com/Locating/showji.com2016234999234.aspx?m=13900008888&output=json&callback=querycallback&timestamp=1493796438586

其中m为手机号码,output为数据格式json,callback为返回动作,timestamp为时间戳,so只要替换其中的m,就能获取新的手机归属地了!

通过抓包分析,响应为:

querycallback({
"Mobile": "13900008888",
"QueryResult": "True",
"TO": "中国移动",
"Corp": "中国移动",
"Province": "新疆",
"City": "乌鲁木齐",
"AreaCode": "0991",
"PostCode": "830000",
"VNO": "",
"Card": ""
});

在querycallback()里面是一个json格式的数据包。对应有手机号、运营商、省份、城市等有用信息,Nice啊!这就是我需要的。

四:有用数据的落地

重点是落地,落到哪里去,最好的最便捷的还是使用python直接支持的sqlite3啦,轻量快捷!

五:代码实现

#coding:utf-8
import sys
import urllib2
import sqlite3
import json
import time
import re


class SQLITETool:
    def __init__(self,databaseName):
        self.databaseName = databaseName
        self.create_db()

    def create_db(self):
        conn = sqlite3.connect(self.databaseName)
        conn.close();
        
    def execute_table(self,sql):
        conn = sqlite3.connect(self.databaseName);
        cursor = conn.cursor();
        try:
            cursor.execute(sql)
        except Exception, e:
            print(Exception,":",e)
        finally:
            cursor.close()
            conn.commit()
            conn.close()


class PhoneInfoSpider:
    def __init__(self,databaseName,phoneSections):
        self.phoneSections = phoneSections
        self.sqlTool = SQLITETool(databaseName)

    def phoneInfoHandler(self,jsonData):
            mobile = jsonData['Mobile'];
            corp = jsonData['Corp'];
            province = jsonData['Province'];
            city = jsonData['City'];
            try:
                sql = 'insert into phone_info_table (mobile, corp, province, city) values(\'{0}\',\'{1}\',\'{2}\',\'{3}\')'.format(mobile,corp,province,city);
                self.sqlTool.execute_table(sql)
            except Exception,e:
                print(Exception,":",e)

    def requestPhoneInfo(self,phoneNum):
        print(phoneNum);
        try:
            #因为有20次/min的ip限制,所以sleep  3s
            time.sleep(3);
            response = urllib2.urlopen('http://v.showji.com/Locating/showji.com2016234999234.aspx?m={0}&output=json&callback=querycallback&timestamp=1484546664567'.format(phoneNum))
            resStr = response.read()
            jsonStr = re.search(r'querycallback\((.*?)\);',resStr,re.S).group(1)
            jsonData = json.loads(jsonStr)
            self.phoneInfoHandler(jsonData)
        except Exception,e:
            print(Exception,":",e)

    def requestAllSections(self):
        #last用于接上次异常退出前的号码
        last = 0
        #自动生成手机号码,后四位补0
        for head in self.phoneSections:
            for i in range(last,10000):
                middle = str(i).zfill(4)
                phoneNum = head+middle+"0000"
                self.requestPhoneInfo(phoneNum)
            last = 0



if __name__ == '__main__':
    reload(sys);
    sys.setdefaultencoding('utf-8');

    #134,135 '136','137','138','139','150','151','152',133','153','180','181','189','177',173','149','182','183','184','178'
    #'157','158','159','187','188','147',   '130','131','132','155','156','185','186','145','176'
    #要爬的号码段
    yys = ['153','180','181','189','177','173','149','182','183','184','178'];
    spider = PhoneInfoSpider('phoneInfo.db',yys)
    sql = 'CREATE TABLE phone_info_table (mobile varchar(11) primary key,corp varchar(32),province varchar(16), city varchar(32));'
    spider.sqlTool.execute_table(sql)
    spider.requestAllSections()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容