爬取手機號碼歸屬地

去年年底,公司需要建個本地的手機號碼歸屬地庫,因為有點時間,又愛好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()
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容