美文网首页
爬取手机号码归属地

爬取手机号码归属地

作者: 飞行员suke | 来源:发表于2017-05-03 17:08 被阅读0次

去年年底,公司需要建个本地的手机号码归属地库,因为有点时间,又爱好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()

相关文章

网友评论

      本文标题:爬取手机号码归属地

      本文链接:https://www.haomeiwen.com/subject/bqnktxtx.html