【问题标题】:Finding the AS Number for IPs (~1M) in a file concurrently同时在文件中查找 IP (~1M) 的 AS 编号
【发布时间】:2020-03-24 14:29:50
【问题描述】:

问题 1:所以我有一个包含一些 1M IP 地址的文件。我必须找到每个人的 AS 编号(IPWhois 或 whois)。我正在阅读该文件,该文件又将其 (.readlines()) 存储在列表中。如果我一个一个地阅读 IP 地址,这将需要几个小时。所以我所做的就是将列表分成一百个子列表(每个子列表 10k 行)并运行 99-100 个进程。我无法弄清楚为什么这仍然需要很多时间。任何帮助,将不胜感激。 [在代码的下部,我正在访问 APnic 站点并检查互联网的百分比被 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 查找有另一个问题,但这是主要问题。另一个问题是 - 许多 IP 的 ASNumber 存在,但 IPWhois 给出的错误如下 - 引发 HTTPError(req.full_url, code, msg, hdrs, fp) urllib.error.HTTPError:HTTP 错误 404:未找到 ipwhois.exceptions.HTTPLookupError:HTTP 查找失败 ....//rdap.afrinic.net/rdap/ip/~someip~,错误代码为 404。 但是当我运行 whois -h whois.cymru.com someip 时,它会返回 AS 编号。]

【问题讨论】:

  • 我的意思是很多时间,几个小时和几个小时。一天,也许吧。
  • 您的原始列表是哪种文件格式?
  • @LTheriault 这是一个文本文件。

标签: python python-3.x multithreading network-programming multiprocessing


【解决方案1】:

所以,除了原始行数之外,看起来一切进展缓慢的原因是 readlines() 返回一个包含文件中每一行的列表,这意味着您现在正在使用这些内存中有 1M 个地址。遍历记录的一种方法是使用上下文管理器,它不会同时将所有行存储在内存中:

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

这里仍然存在问题,因为您最终将有一个大约 1M 的记录列表可供使用。尤其是如果您研究矢量化,您会发现一些小的调整和修复可能会为函数本身的实际应用增加额外的速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多