Поиск номера AS для IP-адресов (~ 1M) в файле одновременно - PullRequest
0 голосов
/ 24 марта 2020

Проблема 1: Итак, у меня есть файл, содержащий несколько 1М IP-адресов. Я должен найти номер AS для каждого из них (IPWhois или whois). Я читаю этот файл, который в свою очередь (.readlines ()) сохраняет его в списке. Если я читаю IP Addr по одному, это займет несколько часов. Итак, я разбил список на сотню подсписков (по 10 тыс. Строк в каждом) и запустил 99-100 процессов. Я не могу понять, почему это все еще занимает слишком много времени. Любая помощь будет оценена. [В нижней части кода я посещаю сайт APni c и проверяю, какой процент от inte rnet занят ASnumber, но это не связано с проблемой.]

from ast import literal_eval
from pprint import pprint
import re
import shlex
import subprocess
from subprocess import Popen, PIPE
# import requests
import os
from ipwhois import IPWhois
from multiprocessing import Process


def form_set(IP_List, asSet, countset):
    #    print("Yay!\n")
    for ip in IP_List:
        try:
            obj = IPWhois(ip.rstrip()).lookup_rdap(
                asn_methods=['dns', 'whois', 'http'])
            asn = obj['asn']
            # print(asn+'\n')
            if (asn[0].isdigit()) == True:
                asnNo = 'AS'+asn
                asSet.add(asnNo)
                #print(str(len(asSet))+'\n')
            else:
                #print(ip)
                countset.add(ip) // IPs for which there is no ASNo.
        except:
            countset.add(ip)
            continue


def main():
    count = 1
    asSet = set()
    file = open('ipList', 'r')
    IPs = file.readlines()
    processes = []
    ip_chunks = [IPs[x:x+10000] for x in range(0, len(IPs), 10000)]
    print(len(ip_chunks))

    countset = set()
    for ipchunk in ip_chunks:
        #        print('Calling for len(ipchunks) = ' + str(len(ipchunk)))
        p = Process(target=form_set, args=(ipchunk, asSet, countset, ))
        p.start()
        processes.append(p)

    for p in processes:
        p.join()

    print(asSet)
    url = 'https://stats.labs.apnic.net/aspop/'
    with requests.Session() as session:
        response = session.get(url)
        pattern = re.compile(
            r"table = new google\.visualization\.arrayToDataTable\((.*?)\);", re.MULTILINE | re.DOTALL)
        data = pattern.search(response.content).group(1)

        data = literal_eval(data)
        colperc = -1
        colasn = -1
        for header in data[0]:
            colperc = colperc + 1
            if header == "% of Internet":
                break

        for header in data[0]:
            colasn = colasn + 1
            if header == "ASN":
                break

        dictData = dict()
        for line in data:
            dictData[line[colasn]] = line[colperc]

        totalpercent = 0.0
        for asNo in asSet:
            if asNo in dictData.keys():
                totalpercent = totalpercent + dictData.get(asNo)

        print(totalpercent)
        print(count)


if __name__ == "__main__":
    main()

[Проблема 2: у меня есть другая проблема с этим поиском ipwhois, но это основная проблема. Другая проблема заключается в следующем: номер ASNumber для многих IP-адресов существует, но IPWhois выдает ошибки, такие как: .HTTPLookupError: Не удалось выполнить поиск HTTP для .... // rdap.afrini c .net / rdap / ip / ~ someip ~ с кодом ошибки 404. Но когда я запускаю whois -h whois.cymru.com someip возвращает номер AS.]

1 Ответ

0 голосов
/ 25 марта 2020

Таким образом, похоже, что причина, по которой все может идти так медленно, кроме необработанного количества строк, заключается в том, что readlines() возвращает список, содержащий каждую строку в файле, то есть вы теперь работаете с этими 1М адресов в памяти. Один из способов перебора записей - использовать менеджер контекста, который не будет хранить все строки в памяти одновременно:

with open('ipList.txt', 'r') as file: 
    for line in file:
        ...

Здесь все еще есть проблема, потому что в конечном итоге у вас будет ~ 1M список записей для работы. Особенно если вы исследуете векторизацию, вы можете найти небольшие изменения и исправления, которые могут добавить дополнительную скорость для фактического применения самой функции.

...