[英]List of IP addresses/hostnames from local network in Python
How can I get a list of the IP addresses or host names from a local network easily in Python?如何在 Python 中轻松地从本地网络获取 IP 地址或主机名列表?
It would be best if it was multi-platform, but it needs to work on Mac OS X first, then others follow.最好是多平台的,但它需要先在 Mac OS X 上运行,然后其他的。
Edit: By local I mean all active addresses within a local network, such as 192.168.xxx.xxx
.编辑:本地是指本地网络中的所有活动地址,例如192.168.xxx.xxx
。
So, if the IP address of my computer (within the local network) is 192.168.1.1
, and I have three other connected computers, I would want it to return the IP addresses 192.168.1.2
, 192.168.1.3
, 192.168.1.4
, and possibly their hostnames.因此,如果我的计算机(在本地网络内)的 IP 地址是192.168.1.1
,并且我连接了另外三台计算机,我希望它返回 IP 地址192.168.1.2
、 192.168.1.3
、 192.168.1.4
和可能是他们的主机名。
If by "local" you mean on the same network segment, then you have to perform the following steps:如果“本地”是指在同一网段上,则必须执行以下步骤:
Or you can just let Python execute nmap externally and pipe the results back into your program.或者你可以让 Python 在外部执行 nmap 并将结果通过管道传回你的程序。
Update : The script is now located on github .更新:该脚本现在位于github 上。
I wrote a small python script , that leverages scapy 's arping()
.我写了一个小的 python 脚本,它利用了scapy的arping()
。
If you know the names of your computers you can use:如果您知道您的计算机的名称,您可以使用:
import socket
IP1 = socket.gethostbyname(socket.gethostname()) # local IP adress of your computer
IP2 = socket.gethostbyname('name_of_your_computer') # IP adress of remote computer
Otherwise you will have to scan for all the IP addresses that follow the same mask as your local computer (IP1), as stated in another answer.否则,您将不得不扫描与本地计算机 (IP1) 具有相同掩码的所有 IP 地址,如另一个答案中所述。
I have collected the following functionality from some other threads and it works for me in Ubuntu.我从其他一些线程中收集了以下功能,它在 Ubuntu 中对我有用。
import os
import socket
import multiprocessing
import subprocess
def pinger(job_q, results_q):
"""
Do Ping
:param job_q:
:param results_q:
:return:
"""
DEVNULL = open(os.devnull, 'w')
while True:
ip = job_q.get()
if ip is None:
break
try:
subprocess.check_call(['ping', '-c1', ip],
stdout=DEVNULL)
results_q.put(ip)
except:
pass
def get_my_ip():
"""
Find my IP address
:return:
"""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
return ip
def map_network(pool_size=255):
"""
Maps the network
:param pool_size: amount of parallel ping processes
:return: list of valid ip addresses
"""
ip_list = list()
# get my IP and compose a base like 192.168.1.xxx
ip_parts = get_my_ip().split('.')
base_ip = ip_parts[0] + '.' + ip_parts[1] + '.' + ip_parts[2] + '.'
# prepare the jobs queue
jobs = multiprocessing.Queue()
results = multiprocessing.Queue()
pool = [multiprocessing.Process(target=pinger, args=(jobs, results)) for i in range(pool_size)]
for p in pool:
p.start()
# cue hte ping processes
for i in range(1, 255):
jobs.put(base_ip + '{0}'.format(i))
for p in pool:
jobs.put(None)
for p in pool:
p.join()
# collect he results
while not results.empty():
ip = results.get()
ip_list.append(ip)
return ip_list
if __name__ == '__main__':
print('Mapping...')
lst = map_network()
print(lst)
For OSX (and Linux), a simple solution is to use either os.popen or os.system and run the arp -a
command.对于 OSX(和 Linux),一个简单的解决方案是使用 os.popen 或 os.system 并运行arp -a
命令。
For example:例如:
devices = []
for device in os.popen('arp -a'): devices.append(device)
This will give you a list of the devices on your local network.这将为您提供本地网络上的设备列表。
I found this network scanner in python article and wrote this short code.我在 python 文章中找到了这个网络扫描仪并写了这个短代码。 It does what you want!它做你想做的! You do however need to know accessible ports for your devices.但是,您确实需要知道设备的可访问端口。 Port 22 is ssh standard and what I am using.端口 22 是 ssh 标准和我正在使用的。 I suppose you could loop over all ports.我想你可以遍历所有端口。 Some defaults are:一些默认值是:
linux: [20, 21, 22, 23, 25, 80, 111, 443, 445, 631, 993, 995]
windows: [135, 137, 138, 139, 445]
mac: [22, 445, 548, 631]
import socket
def connect(hostname, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.setdefaulttimeout(1)
result = sock.connect_ex((hostname, port))
sock.close()
return result == 0
for i in range(0,255):
res = connect("192.168.1."+str(i), 22)
if res:
print("Device found at: ", "192.168.1."+str(i) + ":"+str(22))
EDIT by TheLizzard: TheLizzard编辑:
Using the code above and adding threading:使用上面的代码并添加线程:
from threading import Thread, Lock
from time import perf_counter
from sys import stderr
from time import sleep
import socket
# I changed this from "192.168.1.%i" to "192.168.0.%i"
BASE_IP = "192.168.0.%i"
PORT = 80
class Threader:
"""
This is a class that calls a list of functions in a limited number of
threads. It uses locks to make sure the data is thread safe.
Usage:
from time import sleep
def function(i):
sleep(2)
with threader.print_lock:
print(i)
threader = Threader(10) # The maximum number of threads = 10
for i in range(20):
threader.append(function, i)
threader.start()
threader.join()
This class also provides a lock called: `<Threader>.print_lock`
"""
def __init__(self, threads=30):
self.thread_lock = Lock()
self.functions_lock = Lock()
self.functions = []
self.threads = []
self.nthreads = threads
self.running = True
self.print_lock = Lock()
def stop(self) -> None:
# Signal all worker threads to stop
self.running = False
def append(self, function, *args) -> None:
# Add the function to a list of functions to be run
self.functions.append((function, args))
def start(self) -> None:
# Create a limited number of threads
for i in range(self.nthreads):
thread = Thread(target=self.worker, daemon=True)
# We need to pass in `thread` as a parameter so we
# have to use `<threading.Thread>._args` like this:
thread._args = (thread, )
self.threads.append(thread)
thread.start()
def join(self) -> None:
# Joins the threads one by one until all of them are done.
for thread in self.threads:
thread.join()
def worker(self, thread:Thread) -> None:
# While we are running and there are functions to call:
while self.running and (len(self.functions) > 0):
# Get a function
with self.functions_lock:
function, args = self.functions.pop(0)
# Call that function
function(*args)
# Remove the thread from the list of threads.
# This may cause issues if the user calls `<Threader>.join()`
# But I haven't seen this problem while testing/using it.
with self.thread_lock:
self.threads.remove(thread)
start = perf_counter()
# I didn't need a timeout of 1 so I used 0.1
socket.setdefaulttimeout(0.1)
def connect(hostname, port):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
result = sock.connect_ex((hostname, port))
with threader.print_lock:
if result == 0:
stderr.write(f"[{perf_counter() - start:.5f}] Found {hostname}\n")
threader = Threader(10)
for i in range(255):
threader.append(connect, BASE_IP%i, PORT)
threader.start()
threader.join()
print(f"[{perf_counter() - start:.5f}] Done searching")
input("Press enter to exit.\n? ")
Try:尝试:
import socket
print ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1])
I have done following code to get the IP of MAC known device.我已经完成了以下代码来获取 MAC 已知设备的 IP。 This can be modified accordingly to obtain all IPs with some string manipulation.这可以进行相应的修改,以通过一些字符串操作来获取所有 IP。 Hope this will help you.希望这会帮助你。
#running windows cmd line statement and put output into a string
cmd_out = os.popen("arp -a").read()
line_arr = cmd_out.split('\n')
line_count = len(line_arr)
#search in all lines for ip
for i in range(0, line_count):
y = line_arr[i]
z = y.find(mac_address)
#if mac address is found then get the ip using regex matching
if z > 0:
ip_out= re.search('[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+', y, re.M | re.I)
I have just had the problem.我刚刚遇到了这个问题。 I solved it like this:我是这样解决的:
import kthread #pip install kthread
from time import sleep
import subprocess
def getips():
ipadressen = {}
def ping(ipadresse):
try:
outputcap = subprocess.run([f'ping', ipadresse, '-n', '1'], capture_output=True) #sends only one package, faster
ipadressen[ipadresse] = outputcap
except Exception as Fehler:
print(Fehler)
t = [kthread.KThread(target = ping, name = f"ipgetter{ipend}", args=(f'192.168.0.{ipend}',)) for ipend in range(255)] #prepares threads
[kk.start() for kk in t] #starts 255 threads
while len(ipadressen) < 255:
print('Searching network')
sleep(.3)
alldevices = []
for key, item in ipadressen.items():
if not 'unreachable' in item.stdout.decode('utf-8') and 'failure' not in item.stdout.decode('utf-8'): #checks if there wasn't neither general failure nor 'unrechable host'
alldevices.append(key)
return alldevices
allips = getips() #takes 1.5 seconds on my pc
One of the answers in this question might help you. 此问题中的一个答案可能会对您有所帮助。 There seems to be a platform agnostic version for python, but I haven't tried it yet. python似乎有一个与平台无关的版本,但我还没有尝试过。
Here is a small tool scanip that will help you to get all ip addresses and their corresponding mac addresses in the network (Works on Linux).这是一个小工具scanip ,可以帮助您获取网络中的所有ip地址及其对应的mac地址(适用于Linux)。
https://github.com/vivkv/scanip https://github.com/vivkv/scanip
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.