【Python】扫描局域网存活主机并获取MAC地址、主机名

哈里最近在玩物联网,准备让主机检测手机是否接入wifi从而判断哈里是否回家,因此需要主机时不时扫描一下内网。

废话不多说直接上代码:

import re
import socket
import time

import ping3
"""用pip3 install ping3安装"""
import os
import multiprocessing as mp


def GetPCName(host):
  try:
    r = socket.gethostbyaddr(host)
  except Exception as e:
    # print('GetPCName.e=', e)
    return 'unknown'
  return r[0]


def OutputCmd(cmd):
  r = os.popen(cmd)
  text = r.read()
  r.close()
  return text


def Ping(host):
  pingResult = ping3.ping(host)
  if not pingResult:
    return None
  return {'delay': pingResult, 'name': GetPCName(host)}


class NetWorkTool:
  def __init__(self, ipAddr, startNum=1, endNum=255):
    startTime = time.time()
    allPingIPList = ['{}.{}'.format(ipAddr, i) for i in range(startNum, endNum + 1)]
    with mp.Pool(processes=33) as pool:
      poolResult = pool.map(Ping, allPingIPList)
    allIPInfo = {allPingIPList[i]: poolResult[i] for i in range(len(allPingIPList))}
    # print('allIPInfo=', allIPInfo)
    arpTableText = OutputCmd('arp -a')
    # print('arpTableText=', arpTableText)
    arpTableLines = arpTableText.split('\n')
    result = {}
    for line in arpTableLines:
      ip = re.findall(r'\d+\.\d+\.\d+\.\d+', line)
      if not ip:
        continue
      ip = ip[0]
      if ip not in allIPInfo or allIPInfo[ip] is None:
        continue
      mac = re.findall(r'..-..-..-..-..-..', line)
      if not mac:
        continue
      allIPInfo[ip]['mac'] = mac[0]
      allIPInfo[ip]['ip'] = ip
      result[ip] = allIPInfo[ip]
      # print('ipInfo=', allIPInfo[ip])
    print('扫描用时:{}秒'.format(time.time() - startTime))
    self.allIPInfo = result

  def FindIP(self, findValue, fuzz=True):
    for ipData in self.allIPInfo.values():
      for key in ipData:
        if ipData.get(key) == findValue:
          return ipData
        if not fuzz:
          continue
        if findValue in str(ipData.get(key, '')):
          return ipData
        if re.findall(findValue, str(ipData.get(key, ''))):
          return ipData
    return None


if __name__ == '__main__':
  tool = NetWorkTool('192.168.31')
  print('网络详情=', tool.allIPInfo)
  findResult = tool.FindIP('8T')
  print('查询结果=', findResult)

优点:只需要安装一个ping3库,哈里看了scapy,还要装软件啥的太麻烦了。

瑕疵:不知道是不是multiprocessing库的锅,偶尔有些地址ping不通,但是单独拎出来又可以ping通,导致有时候获取不到。如果体验不佳后面会改成用threading库。

以上: >

你可能感兴趣的:(我的Python朋友,python,网络)