Получаем общедоступные данные по номеру телефона с помощью Python

Спасибо. Это будет благородно с вашей стороны.
Думаю, я многому у вас научусь.

В общем, я тут немного посидел, подумал, и вот, что у меня получилось...

Во вложении к ответу будут три версии файла:
- Первая версия - это собственно вчерашняя, то есть, практически оригинальная;
- Вторая версия - это переделанная логика без потоков;
- Третья версия - то же самое, что и вторая, но с использованием потоков.

У меня нет большого количества номеров, а фейкер заводить неохота. В общем, тестировал на том, что нашел.
Нашел я порядка 130 номеров. Конечно, для полноценного теста маловато, но да ладно.
Тестировал на одном и том же файле все три версии.

Скрины:

Первая версия (время проверки номеров):

01_orig_time.png


Вторая версия (время проверки номеров):

02_without_threads.png


Третья версия (время проверки номеров):

03_with_threads.png


Как видно, здесь по скорости третья версия, с потоками не особо выделилась. Но, думаю,
что если у вас будет большой массив номеров, то скорость будет различаться.

Такие вот дела. Код во вложении.

Ну и да, фоннамберс можете выпилить. Я его оставил, так, на всякий случай. Потому как если вы его совсем выпилите, вам нужно
будет написать обработку ошибок для тех номеров, которые не попадут под российские.
 

Вложения

Последнее редактирование:
  • Нравится
Реакции: UnnamedUser и bigsky
Спасибо. Это будет благородно с вашей стороны.
Думаю, я многому у вас научусь.

Сделал версии без фоннамбера. Добавил список, куда будут складываться нераспознанные номера, а потом сохраняться в текстовый документ.
 

Вложения

  • Нравится
Реакции: bigsky
@Johan Van, Большое спасибо за Ваш труд 🤝
Обязательно предоставлю обратную связь о коде.
 
@Johan Van, Здравствуйте.
Код из архива zone_03_no_ph_thread.zip работает потрясающе – высокая скорость. Спасибо за Ваш труд.

@Johan Van, как будет выглядеть код файла phone_no_ph_thread.py из архива zone_03_no_ph_thread.zip для работы только с номерами российских операторов если:
1. номера в файле numbers.txt будут только такого формата/вида:
79230041595
79230910795
79237860404
79230542647
79231751758
79232679465
79239556508
79235545728
79236188444
79233044905
2. от кода файла phone_no_ph_thread.py нужно только определение оператора связи.
3. в файл numbers_find.txt нужен вывод только операторов связи каждого номера, а если определение оператора номера не возможно, то вместо него была строка "– – –"
ПАО "МегаФон"
ПАО "МегаФон"
ПАО "МегаФон"
– – –
ПАО "МегаФон"
ПАО "МегаФон"
– – –
ПАО "МегаФон"
4. вывод нераспознанных номеров в файл unknown_number.txt не нужен, потому как они будут в файле numbers_find.txt в виде "– – –"
 
@Johan Van, Здравствуйте.
Код из архива zone_03_no_ph_thread.zip работает потрясающе – высокая скорость. Спасибо за Ваш труд.

@Johan Van, как будет выглядеть код файла phone_no_ph_thread.py из архива zone_03_no_ph_thread.zip для работы только с номерами российских операторов если:
1. номера в файле numbers.txt будут только такого формата/вида:
79230041595
79230910795
79237860404
79230542647
79231751758
79232679465
79239556508
79235545728
79236188444
79233044905
2. от кода файла phone_no_ph_thread.py нужно только определение оператора связи.
3. в файл numbers_find.txt нужен вывод только операторов связи каждого номера, а если определение оператора номера не возможно, то вместо него была строка "– – –"
ПАО "МегаФон"
ПАО "МегаФон"
ПАО "МегаФон"
– – –
ПАО "МегаФон"
ПАО "МегаФон"
– – –
ПАО "МегаФон"
4. вывод нераспознанных номеров в файл unknown_number.txt не нужен, потому как они будут в файле numbers_find.txt в виде "– – –"

Я конечно извиняюсь, но вы уже мне просто техзадание какое-то даете. Что выходит за рамки простой взаимопомощи. Все, что вы сейчас описали, вы можете сделать самостоятельно, достаточно лишь подправить добавление данных в список. Ну и, собственно, если вывод не нужен, можете просто убрать эту часть.

Если вам данный код нужен для выполнения какой-то работы, то рекомендую разобраться в его работе, чтобы иметь возможность самому исправлять возникающие неполадки или вносить изменения в код по мере необходимости. Тем более, что данный код не выглядит довольно сложным.

Я конечно же могу сделать то, что вы здесь написали, но вы только представьте, если я буду делать все то, что меня просят просто так, то все мое время будет уходить на выполнение, как вам кажется, небольших, но отнимающих определенное время заданий. Вопрос в том, а зачем это мне? Я же не настолько "добрый самаритянин". Да, я могу что-то подсказать, но выполнять все, так, как вам этого захотелось в данный момент, просто потому, что один раз вам пошли навстречу... без обид, мне не особо нужно.

Цель статьи не в том, чтобы дать вам готовое решение. Хотя, кому-то оно будет достаточным в том виде, в котором есть. А в том, чтобы натолкнуть вас на мысль о том, что можно сделать так-то и так-то. Переделка кода под ваши нужны - это уже задача только ваша.

Я понимаю ваше желание сделать код. Но поймите и меня. У меня есть другие дела и постоянно решать задачи не всегда представляется возможным. Как-то так. Извините, если обидел.
 
  • Нравится
Реакции: f22, UnnamedUser и bigsky
@Johan Van, Здравствуйте.
Код из архива zone_03_no_ph_thread.zip работает потрясающе – высокая скорость. Спасибо за Ваш труд.

@Johan Van, как будет выглядеть код файла phone_no_ph_thread.py из архива zone_03_no_ph_thread.zip для работы только с номерами российских операторов если:
1. номера в файле numbers.txt будут только такого формата/вида:
79230041595
79230910795
79237860404
79230542647
79231751758
79232679465
79239556508
79235545728
79236188444
79233044905
2. от кода файла phone_no_ph_thread.py нужно только определение оператора связи.
3. в файл numbers_find.txt нужен вывод только операторов связи каждого номера, а если определение оператора номера не возможно, то вместо него была строка "– – –"
ПАО "МегаФон"
ПАО "МегаФон"
ПАО "МегаФон"
– – –
ПАО "МегаФон"
ПАО "МегаФон"
– – –
ПАО "МегаФон"
4. вывод нераспознанных номеров в файл unknown_number.txt не нужен, потому как они будут в файле numbers_find.txt в виде "– – –"

В общем, код я переделал. Однако, для того, чтобы вы понимали, номер телефона в выводе в файл придется оставить потому, что потоки завершают свою работу не по порядку, а потому у вас в файле вывод будет не таким, как в файле с номерами телефонов. Именно для того, чтобы после можно было понять, что к чему относиться, и нужен номер телефона. Тем более, его можно потом легко распарсить с помощью того же питона. Так как формат записи имеет разделитель ":", по которому можно разбить файл. При необходимости. Если вас не смущает порядок добавления номеров, то вот, нужно будет удалить то, что в скобках и двоеточие:

001.png


002.png



Python:
import csv
import json
import sys
import time
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path

def_9xx = dict()
zone_t = dict()
number_info = []


def russia_num(phone: str):
    # Делаем проверку: если номера начинаются на 7 или 8, а следующая цифра 9,
    # будем считать, что это российский номер. Запускаем функцию поиска оператора.
    if phone[0:1] in ["8", "7"] and phone[1:2] == "9":
        zone_find(phone[1:4], phone[4:], phone)
    # Здесь проверяем те номера, которые начинаются на +, так как порядок цифр,
    # за счет добавления "+" немного другой. То есть, если обратите внимание,
    # в функцию поиска оператора передаются несколько другие срезы.
    elif phone[0:1] == "+" and phone[2:3] == "9":
        zone_find(phone[2:5], phone[5:], phone)
    # Добавляем те номера, которые не прошли проверку на российские в список,
    # как неопределенные.
    else:
        number_info.append(f'{phone}: "---"')


def zone_find(zone: str, number: str, phone: str):
    global def_9xx, zone_t, number_info
    # Итерируемся по словарю из csv. Проверяем, не равна ли переданная в функцию зона
    # текущему значению в словаре. Если равна, итерируемся по значениям, которые представляют собой также словарь,
    # ключами в котором являются диапазоны операторов, так как это уникальные значения, а значениями оператор
    # и регион.
    for zn in def_9xx:
        if zone == zn:
            for rng in def_9xx[zn]:
                # Проверяем, входит ли номер телефона в диапазон оператора. Если нет, двигаемся дальше.
                # Если входит, забираем оператора (провайдера), получаем из него регион, забираем из словаря
                # временную зону и выводим все это в терминал. Также добавляем номер телефона и оператора
                # в список с определенными операторами.
                if int(number) in range(int(rng.split(",")[0]), int(rng.split(",")[1])):
                    try:
                        print(f'\n[+] Информация о номере: {phone}:\n    - Провайдер (ОпСоС): '
                              f'{def_9xx[zn][rng].split(",")[0].strip()}\n    '
                              f'- Регион: {def_9xx[zn][rng].split(",")[1].strip()}\n    - Часовой пояс: '
                              f'{zone_t[def_9xx[zn][rng].split(",")[1].strip()]}')
                        number_info.append(f'{phone}: {def_9xx[zn][rng].split(",")[0].strip()}')
                        return
                    except KeyError:
                        print(f'\n[+] Информация о номере: {phone}:\n    - Провайдер (ОпСоС): '
                              f'{def_9xx[zn][rng].split(",")[0].strip()}\n    '
                              f'- Регион: {def_9xx[zn][rng].split(",")[1].strip()}')
                        number_info.append(f'{phone}: {def_9xx[zn][rng].split(",")[0].strip()}')
                        return
    number_info.append(f'{phone}: "---"')


def conv():
    # Здесь открываем файл csv, перебираем его построчно, делим каждую строку
    # и добавляем в словарь, ключом к каждому разделу будет зона, то есть, 900 и т.д.
    global def_9xx
    with open(Path.cwd() / 'guides' / 'DEF-9xx.csv', "r", encoding='utf-8') as f:
        readers = csv.reader(f, delimiter="\t")
        for num, line in enumerate(readers):
            if num != 0:
                ln = line[0].split(";")
                if ln[0] not in def_9xx:
                    def_9xx[ln[0]] = dict()
                opsos = f'{ln[4]}, {ln[5]}'
                rng = f'{ln[1]},{ln[2]}'
                def_9xx[ln[0]].update({rng: opsos})


def main():
    global zone_t, number_info

    # Проверяем наличие словаря с временными зонами. Если его нет - завершаем работу.
    # Если словарь есть, открываем его и добавляем содержимое в словарь, который определен
    # глобально. То есть, содержимое словаря будет находиться в памяти для ускорения поиска данных.
    if not (Path.cwd() / 'guides' / 'zone.json').exists():
        print("Отсутствует справочник с временными зонами 'zone.json'")
        sys.exit(0)
    with open(Path.cwd() / 'guides' / 'zone.json', 'r', encoding='utf-8') as f:
        zone_t.update(json.load(f))

    # Производим проверку на наличие файла с диапазонами. Если его нет - завершаем работу.
    # Если файл есть, запускаем функцию для конвертации csv в словарь.
    if not (Path.cwd() / 'guides' / 'DEF-9xx.csv').exists():
        print("Отсутствует справочник с диапазонами номеров операторов 'DEF-9xx.csv'")
        sys.exit(0)
    conv()

    # Запрашиваем у пользователя путь к файлу с номерами. Если путь неверный - выходим из скрипта.
    # В переменную t присваиваем текущее время. Это нужно, чтобы определить время работы.
    path = input("Введите путь к файлу с номерами: ")
    t = time.monotonic()
    if not Path(path).exists() or not Path(path).is_file() or not path:
        print("Введенного пути не существует")
        sys.exit(0)

    # Выводим в терминал сообщение. Открываем файл с номерами телефона.
    # Итерируемся по файлу построчно. Очищаем от скобок, пустых мест и тире.
    # Проверяем первый знак. Если он +, проверяем второй - если 7, значит - Россия.
    # Запускаем поток, который запускает функцию russia_num и передает в нее номер.
    # Если номер начинается с 7 или 8, тоже считаем, что это Россия и,
    # запускаем поток, который запускает функцию russia_num и передает в нее номер.
    # Если же номер не определен, как российский и не принадлежит сотовым операторам,
    # в рамках текущего скрипта он определен не будет. Добавляем его в список с неопределенным оператором.
    print('\n* ИНФОРМАЦИЯ О НОМЕРЕ ТЕЛЕФОНА. РЕГИОН, ОПЕРАТОР И ЧАСОВОЙ ПОЯС *\n')
    with open(path, 'r', encoding='utf-8') as file:
        with ThreadPoolExecutor(max_workers=5) as executor:
            for phone in file.readlines():
                phone = phone.replace("-", "").replace("(", "").replace(")", "").replace(" ", "").strip()
                if phone[0:1] == "+":
                    if phone[1:2] == "7":
                        executor.submit(russia_num, phone=phone)
                elif phone[0:1] == "7":
                    executor.submit(russia_num, phone=phone)
                elif phone[0:1] == "8":
                    executor.submit(russia_num, phone=phone)
                else:
                    number_info.append(f'{phone}: "---"')

    # Проверяем, не пуст ли список с операторами. Если нет,
    # открываем файл на запись, итерируемся по списку с операторами
    # и добавляем в открытый файл элементы списка.
    # После выводим в терминал время работы функции.
    if number_info:
        with open('numbers_find.txt', 'w', encoding='utf-8') as fl:
            for item in number_info:
                fl.write(f'{item}\n')

    print(f'\nВремя поиска номеров: '
          f'{(int(time.monotonic() - t) // 3600) % 24:d} ч. '
          f'{(int(time.monotonic() - t) // 60) % 60:02d} м. '
          f'{int(time.monotonic() - t) % 60:02d} с.')
    print(time.monotonic() - t)


if __name__ == "__main__":
    main()

ну и да, номера начинающиеся с 7 тоже принимаются теперь нормально.
В теории, думаю, что можно было бы также проверять и номера не сотовых операторов, загрузив соответствующий файл с сайта.

003.png


Как видите, здесь широкое поле для деятельности. Нужно только добавить в код формирование словарей из csv и проверку по сформированным словарям. Алгоритм, думаю, будет похожим.
 
Последнее редактирование:
  • Нравится
Реакции: f22 и bigsky
Я конечно извиняюсь, но вы уже мне просто техзадание какое-то даете. Что выходит за рамки простой взаимопомощи. Все, что вы сейчас описали, вы можете сделать самостоятельно, достаточно лишь подправить добавление данных в список. Ну и, собственно, если вывод не нужен, можете просто убрать эту часть.

Если вам данный код нужен для выполнения какой-то работы, то рекомендую разобраться в его работе, чтобы иметь возможность самому исправлять возникающие неполадки или вносить изменения в код по мере необходимости. Тем более, что данный код не выглядит довольно сложным.

Я конечно же могу сделать то, что вы здесь написали, но вы только представьте, если я буду делать все то, что меня просят просто так, то все мое время будет уходить на выполнение, как вам кажется, небольших, но отнимающих определенное время заданий. Вопрос в том, а зачем это мне? Я же не настолько "добрый самаритянин". Да, я могу что-то подсказать, но выполнять все, так, как вам этого захотелось в данный момент, просто потому, что один раз вам пошли навстречу... без обид, мне не особо нужно.

Цель статьи не в том, чтобы дать вам готовое решение. Хотя, кому-то оно будет достаточным в том виде, в котором есть. А в том, чтобы натолкнуть вас на мысль о том, что можно сделать так-то и так-то. Переделка кода под ваши нужны - это уже задача только ваша.

Я понимаю ваше желание сделать код. Но поймите и меня. У меня есть другие дела и постоянно решать задачи не всегда представляется возможным. Как-то так. Извините, если обидел.
@Johan Van,
приблизительно такой ответ от Вас был ожидаем, потому как я злоупотребила Вашим радушием.
Вы действительно уже сделали большой объём работы по этому вопросу. От меня Вам бесконечная благодарность за это. Как дань уважения, я постараюсь разобраться в коде и доработать его под мои задачи. Я обязательно поделюсь с Вами полученным результатом, если осилю поставленную перед собой задачу.
 
@Johan Van,
приблизительно такой ответ от Вас был ожидаем, потому как я злоупотребила Вашим радушием.
Вы действительно уже сделали большой объём работы по этому вопросу. От меня Вам бесконечная благодарность за это. Как дань уважения, я постараюсь разобраться в коде и доработать его под мои задачи. Я обязательно поделюсь с Вами полученным результатом, если осилю поставленную перед собой задачу.

Я код поправил. Посмотрите предыдущее сообщение. Просто, это для вас. на будущее. Для примера, скажу, что на Stack Overflow с вами бы даже не стали разговаривать, а сразу же заминусовали. Пока вы не предоставили бы код. Там не любят писать за вас решения, а именно подсказывают, если знают варианты решения проблемы. Вы же, действительно, попытались "злоупотребить", не попытавшись разобраться самостоятельно.
 
  • Нравится
Реакции: bigsky
У меня один вопрос, поскольку я даже не знаю как это всё утроено, хоть подскажите как запустить это всё
 
А что делать если выдает такую ошибку
Traceback (most recent call last):
File "C:\Users\никита\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.11\kod.py", line 86, in <module>
main()
File "C:\Users\никита\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.11\kod.py", line 76, in main
russia_num(phone)
File "C:\Users\никита\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.11\kod.py", line 17, in russia_num
csv_read(num_one, two_num, phone)
File "C:\Users\никита\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.11\kod.py", line 27, in csv_read
with open('zone.json', 'r', encoding='utf-8') as f:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'zone.json'
 
А что делать если выдает такую ошибку
Traceback (most recent call last):
File "C:\Users\никита\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.11\kod.py", line 86, in <module>
main()
File "C:\Users\никита\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.11\kod.py", line 76, in main
russia_num(phone)
File "C:\Users\никита\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.11\kod.py", line 17, in russia_num
csv_read(num_one, two_num, phone)
File "C:\Users\никита\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.11\kod.py", line 27, in csv_read
with open('zone.json', 'r', encoding='utf-8') as f:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'zone.json'

Скрипт просто не находит файл json. Нужно его скачать из статьи и положить в папку со скриптом. Вот ссылка на скачивание данного файла из статьи: https://codeby.net/attachments/zone-zip.60301/
 
Отличный сервис smspoisk.ru , определял местоположение ребенка, как мне очень полезно это знать
 
Traceback (most recent call last):
File "C:/Users/Администратор/Desktop/address.py", line 85, in <module>
main()
File "C:/Users/Администратор/Desktop/address.py", line 75, in main
russia_num(phone)
File "C:/Users/Администратор/Desktop/address.py", line 16, in russia_num
csv_read(num_one, two_num, phone)
File "C:/Users/Администратор/Desktop/address.py", line 28, in csv_read
with open("DEF-9xx.csv", "r", encoding='utf-8') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'DEF-9xx.csv'

как исправить эту ошибку?
 
Traceback (most recent call last):
File "C:/Users/Администратор/Desktop/address.py", line 85, in <module>
main()
File "C:/Users/Администратор/Desktop/address.py", line 75, in main
russia_num(phone)
File "C:/Users/Администратор/Desktop/address.py", line 16, in russia_num
csv_read(num_one, two_num, phone)
File "C:/Users/Администратор/Desktop/address.py", line 28, in csv_read
with open("DEF-9xx.csv", "r", encoding='utf-8') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'DEF-9xx.csv'

как исправить эту ошибку?
Нужно положить файл ".csv" в директорию скрипта из которого он считывается. Взять данный файл можно тут:

Для наглядности:

screenshot1.png


И не забудьте скачать файл во вложении к статье. Иначе будет еще одна ошибка с отсутствием файла.
 
  • Нравится
Реакции: bayland
Нужно положить файл ".csv" в директорию скрипта из которого он считывается. Взять данный файл можно тут:

Для наглядности:

Посмотреть вложение 73391

И не забудьте скачать файл во вложении к статье. Иначе будет еще одна ошибка с отсутствием файла.
почему то сайт с файлом не загружается, можете его скинуть?
 
Добрый день.
Даже зарегистрировался, чтобы прокомментировать)
Спасибо большое за инфу по реестру с операторами, очень круто, не знал.

По поводу корректности введенного номера - вы пишете, что вычистить никак от лишних символов не получится - но это не совсем верно.
Нужно воспользоваться регулярками.
Я сам часто предобрабатываю номера телефонов, пользуюсь вот такой самописной функцией:


Python:
def num_cleaner(row, col='Мобильный телефон'):
    text = str(row[col])
    
    if '+' in text:
        text = text.split('+')[1]

    if '.' in text:
        text = text.split('.')[0]
  
    try:
        text_fix = re.sub(r'\D+','', text)
        if len(text_fix) == 11:
            
            text_fix = re.sub(r'^8{1}', r'7', text_fix)
            
        if len(text_fix) == 10 and text_fix[0] == '9':
            text_fix = '7' + text_fix



    except:
        text_fix = 0
    
    return text_fix

Она не универсальна для нероссийских номеров, но работать должно)
 
спс давно хотел сделать так . применю в своём тг боте
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!