本文目录导读:

我来介绍几种常用的局域网设备扫描方法,包括简单的脚本和工具。
使用 Python 脚本扫描
基础 ping 扫描
#!/usr/bin/env python3
import subprocess
import ipaddress
import concurrent.futures
def ping_host(ip):
"""Ping 单个主机"""
try:
# Windows 使用 -n,Linux/Mac 使用 -c
result = subprocess.run(
['ping', '-c', '1', '-W', '1', str(ip)],
capture_output=True,
timeout=2
)
if result.returncode == 0:
return str(ip), True
return str(ip), False
except:
return str(ip), False
def scan_network(network):
"""扫描整个网段"""
network = ipaddress.ip_network(network, strict=False)
devices = []
# 使用线程池加速扫描
with concurrent.futures.ThreadPoolExecutor(max_workers=50) as executor:
futures = {executor.submit(ping_host, ip): ip for ip in network.hosts()}
for future in concurrent.futures.as_completed(futures):
ip, status = future.result()
if status:
devices.append(ip)
print(f"发现设备: {ip}")
return devices
if __name__ == "__main__":
# 扫描 192.168.1.0/24 网段
network = "192.168.1.0/24"
print(f"开始扫描 {network}...")
devices = scan_network(network)
print(f"\n发现 {len(devices)} 个设备:")
for device in devices:
print(device)
高级扫描(获取主机名和MAC地址)
#!/usr/bin/env python3
import subprocess
import json
import re
import ipaddress
import platform
class NetworkScanner:
def __init__(self, network):
self.network = ipaddress.ip_network(network, strict=False)
self.devices = []
def get_arp_table(self):
"""获取ARP表"""
system = platform.system()
if system == "Windows":
result = subprocess.run(['arp', '-a'], capture_output=True, text=True)
else: # Linux/Mac
result = subprocess.run(['arp', '-a'], capture_output=True, text=True)
return self.parse_arp_output(result.stdout)
def parse_arp_output(self, output):
"""解析ARP输出"""
entries = {}
for line in output.split('\n'):
match = re.search(r'(\d+\.\d+\.\d+\.\d+)\s+.*?([0-9a-fA-F:]{17})', line)
if match:
ip = match.group(1)
mac = match.group(2)
entries[ip] = mac
return entries
def get_device_info(self, ip):
"""获取设备信息"""
info = {'ip': ip, 'hostname': None, 'mac': None}
# 获取主机名
try:
import socket
hostname = socket.gethostbyaddr(str(ip))
info['hostname'] = hostname[0]
except:
pass
return info
def scan(self):
"""执行扫描"""
print(f"正在扫描 {self.network}...")
# 获取ARP表
arp_entries = self.get_arp_table()
for ip in self.network.hosts():
ip_str = str(ip)
device_info = self.get_device_info(ip_str)
if ip_str in arp_entries:
device_info['mac'] = arp_entries[ip_str]
# Ping 测试
try:
result = subprocess.run(
['ping', '-c', '1', '-W', '1', ip_str],
capture_output=True,
timeout=2
)
if result.returncode == 0:
device_info['status'] = 'online'
self.devices.append(device_info)
print(f"发现: {ip_str} - {device_info.get('hostname', 'unknown')} - {device_info.get('mac', 'unknown')}")
except:
pass
return self.devices
if __name__ == "__main__":
scanner = NetworkScanner("192.168.1.0/24")
devices = scanner.scan()
print(f"\n共发现 {len(devices)} 个设备")
使用 Bash 脚本(Linux/Mac)
#!/bin/bash
# 定义网段
NETWORK="192.168.1"
echo "扫描 ${NETWORK}.0/24 网段..."
# 循环 ping
for i in {1..254}; do
ip="${NETWORK}.${i}"
# Ping 测试
ping -c 1 -W 1 $ip > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "发现设备: $ip"
# 获取主机名
hostname=$(host $ip 2>/dev/null | cut -d' ' -f5)
if [ ! -z "$hostname" ]; then
echo " 主机名: $hostname"
fi
# 获取MAC地址 (需要 arp 命令)
mac=$(arp -n $ip 2>/dev/null | grep -oP '([0-9a-f]{2}:){5}[0-9a-f]{2}')
if [ ! -z "$mac" ]; then
echo " MAC地址: $mac"
fi
echo "---"
fi
done
echo "扫描完成!"
使用 nmap 工具(推荐)
nmap 是最强大的网络扫描工具之一:
安装 nmap
# Linux sudo apt-get install nmap # Mac brew install nmap # Windows # 从 https://nmap.org/download.html 下载安装
基础扫描命令
# 简单扫描 nmap -sn 192.168.1.0/24 # 详细扫描(显示端口和服务) nmap -sV 192.168.1.0/24 # 快速扫描(-T4 加速) nmap -T4 -F 192.168.1.0/24 # 输出为可解析格式 nmap -sn 192.168.1.0/24 -oG - | grep "Up"
使用 Python 调用 nmap
#!/usr/bin/env python3
import subprocess
import re
def scan_with_nmap(network):
"""使用 nmap 扫描"""
cmd = ['nmap', '-sn', network]
result = subprocess.run(cmd, capture_output=True, text=True)
devices = []
for line in result.stdout.split('\n'):
if "Nmap scan report for" in line:
ip = re.search(r'\d+\.\d+\.\d+\.\d+', line)
if ip:
devices.append(ip.group())
print(f"发现设备: {ip.group()}")
return devices
if __name__ == "__main__":
devices = scan_with_nmap("192.168.1.0/24")
print(f"\n共发现 {len(devices)} 个设备")
综合扫描脚本
#!/usr/bin/env python3
"""
局域网设备综合扫描脚本
支持多种扫描方式,输出格式化结果
"""
import subprocess
import ipaddress
import concurrent.futures
import socket
import time
import json
from datetime import datetime
class NetworkScanner:
def __init__(self, network="192.168.1.0/24", timeout=1):
self.network = ipaddress.ip_network(network, strict=False)
self.timeout = timeout
self.devices = []
def ping_host(self, ip):
"""Ping 测试"""
try:
# Windows 使用 -n 1,Linux/Mac 使用 -c 1
param = '-n' if subprocess.run(['ping', '-n', '1', 'localhost'],
capture_output=True).returncode == 0 else '-c'
result = subprocess.run(
['ping', param, '1', '-W', str(self.timeout), str(ip)],
capture_output=True,
timeout=self.timeout + 1
)
return result.returncode == 0
except:
return False
def get_hostname(self, ip):
"""获取主机名"""
try:
return socket.gethostbyaddr(str(ip))[0]
except:
return None
def get_mac_from_arp(self, ip):
"""从ARP表获取MAC地址"""
try:
result = subprocess.run(['arp', '-a', str(ip)],
capture_output=True, text=True)
# 匹配MAC地址格式
mac_match = re.search(r'([0-9a-fA-F]{2}[-:]){5}[0-9a-fA-F]{2}',
result.stdout)
if mac_match:
return mac_match.group()
except:
pass
return None
def scan_host(self, ip):
"""扫描单个主机"""
ip_str = str(ip)
info = {'ip': ip_str, 'status': 'offline'}
if self.ping_host(ip):
info['status'] = 'online'
info['hostname'] = self.get_hostname(ip)
info['mac'] = self.get_mac_from_arp(ip)
return info
def scan_network(self):
"""扫描整个网段"""
print(f"[{datetime.now().strftime('%H:%M:%S')}] 开始扫描 {self.network}")
print("=" * 50)
# 使用线程池并行扫描
with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor:
futures = {executor.submit(self.scan_host, ip): ip
for ip in self.network.hosts()}
for future in concurrent.futures.as_completed(futures):
device = future.result()
if device['status'] == 'online':
self.devices.append(device)
return self.devices
def print_results(self):
"""打印结果"""
print(f"\n{'='*50}")
print(f"扫描结果: 发现 {len(self.devices)} 个在线设备")
print(f"{'='*50}")
print(f"{'IP地址':<15} {'主机名':<20} {'MAC地址':<18}")
print("-" * 55)
for device in self.devices:
hostname = device.get('hostname', '') or ''
mac = device.get('mac', '') or ''
print(f"{device['ip']:<15} {hostname:<20} {mac:<18}")
def export_json(self, filename="scan_result.json"):
"""导出为JSON"""
with open(filename, 'w', encoding='utf-8') as f:
json.dump({
'scan_time': datetime.now().isoformat(),
'network': str(self.network),
'devices': self.devices
}, f, indent=2)
print(f"结果已导出到 {filename}")
if __name__ == "__main__":
import re
# 自动检测网段
result = subprocess.run(['ipconfig' if subprocess.run(['ipconfig'],
capture_output=True).returncode == 0 else 'ifconfig'],
capture_output=True, text=True)
# 简单提取IP
ip_match = re.search(r'192\.168\.\d+\.\d+', result.stdout)
if ip_match:
base_ip = '.'.join(ip_match.group().split('.')[:3])
network = f"{base_ip}.0/24"
else:
network = "192.168.1.0/24"
scanner = NetworkScanner(network)
scanner.scan_network()
scanner.print_results()
scanner.export_json()
使用说明
- 权限要求:某些操作可能需要root/管理员权限
- 性能优化:使用线程池并行扫描可大大加快速度
- 结果输出:支持控制台输出和JSON导出
- 跨平台:脚本兼容Windows/Linux/Mac
注意事项
- ⚠️ 仅在自己的网络中进行扫描
- 扫描前确认有权限进行网络探测
- 某些网络设备和安全软件可能会阻止扫描
- 企业网络中的扫描可能需要IT部门授权
这些脚本可以实现基本的局域网设备扫描,根据具体需求选择合适的方案即可。