11"""
2- A module for matching Mobile Country Codes (MCC) and Mobile Network Codes (MNC)
3- against a JSON dataset scraped from https://www.mcc-mnc.com/.
4-
5- References:
6- - Original codebase: https://github.com/jbjulia/mcc-mnc
7- This module is based on the code from the GitHub repository linked above.
8- It provides functionality to match MCCs and MNCs against a JSON dataset
9- containing Public Land Mobile Network (PLMN) information scraped from the
10- MCC-MNC website.
2+ A module for matching Mobile Country Codes (MCC) and Mobile Network Codes (MNC)
3+ against a JSON dataset from https://www.mcc-mnc.com/.
114"""
125
136import json
169from urllib .error import URLError
1710from urllib .request import urlopen
1811
19- from bs4 import BeautifulSoup
2012from tqdm import tqdm
2113
22- MCC_MNC_URL = "https://www. mcc-mnc.com/"
14+ MCC_MNC_API_URL = "https://mcc-mnc.com/api/v1/mcc-mnc.php "
2315JSON_PATH = os .path .join (os .path .dirname (__file__ ), "mccmnc.json" )
2416
2517
@@ -62,45 +54,50 @@ def find_matches(
6254
6355def update ():
6456 """
65- Update the JSON data by scraping the MCC-MNC website .
57+ Update the JSON data by fetching from the MCC-MNC API .
6658
6759 Returns:
6860 None
6961 """
7062 try :
71- with urlopen (MCC_MNC_URL ) as raw :
72- print (f"Decoding raw HTML from { MCC_MNC_URL } " )
73- soup = BeautifulSoup (raw , features = "html.parser" )
63+ print (f"Fetching MCC-MNC data from API: { MCC_MNC_API_URL } " )
64+ with urlopen (MCC_MNC_API_URL , timeout = 30 ) as response :
65+ api_data = json .loads (response .read ().decode ("utf-8" ))
66+
67+ if "data" not in api_data :
68+ print ("Error: Invalid API response format" )
69+ sys .exit (1 )
70+
71+ entries = api_data ["data" ]
72+ total_entries = len (entries )
73+ print (f"Received { total_entries } entries from API" )
7474
7575 if os .path .exists (JSON_PATH ):
7676 print (f"Removing old JSON dictionary { JSON_PATH } ." )
7777 os .remove (JSON_PATH )
7878
7979 print (f"Creating new JSON dictionary { JSON_PATH } ." )
8080 json_data = {}
81- table = soup .find ("table" )
82- rows = table .find_all ("tr" )[1 :] # Skip the header
83- total_rows = len (rows )
81+
8482 progress_bar = tqdm (
85- total = total_rows ,
83+ total = total_entries ,
8684 bar_format = "{l_bar}{bar}| {n_fmt}/{total_fmt}" ,
8785 colour = "blue" ,
8886 )
8987
90- for i , row in enumerate (rows , start = 1 ):
91- cols = row .find_all ("td" )
92- mcc = cols [0 ].text
93- mnc = cols [1 ].text
88+ for i , entry in enumerate (entries , start = 1 ):
89+ mcc = entry .get ("mcc" , "" )
90+ mnc = entry .get ("mnc" , "" )
9491 plmn = mcc + mnc # MCC + MNC
9592 json_data [plmn ] = {
9693 "MCC" : mcc ,
9794 "MNC" : mnc ,
98- "ISO" : cols [ 2 ]. text ,
99- "COUNTRY" : cols [ 3 ]. text ,
100- "CC" : cols [ 4 ]. text ,
101- "NETWORK" : cols [ 5 ]. text . strip () if cols [ 5 ]. text else "unknown" ,
95+ "ISO" : entry . get ( "iso" , "" ) ,
96+ "COUNTRY" : entry . get ( "country" , "" ) ,
97+ "CC" : entry . get ( "countryCode" , "" ) ,
98+ "NETWORK" : entry . get ( "network" , "unknown" ) ,
10299 }
103- progress_bar .set_description (f"Processing row { i } /{ total_rows } " )
100+ progress_bar .set_description (f"Processing entry { i } /{ total_entries } " )
104101 progress_bar .update (1 )
105102
106103 progress_bar .close ()
@@ -109,6 +106,11 @@ def update():
109106 print (f"\n Saving JSON dictionary to { JSON_PATH } ." )
110107 json .dump (json_data , json_file , indent = 4 , sort_keys = True )
111108
109+ print (f"Successfully updated MCC-MNC data with { len (json_data )} entries." )
110+
112111 except URLError as e :
113- print (f"Error downloading file: { e } " )
112+ print (f"Error downloading from API: { e } " )
113+ sys .exit (1 )
114+ except json .JSONDecodeError as e :
115+ print (f"Error parsing JSON response: { e } " )
114116 sys .exit (1 )
0 commit comments