怎样用脚本自动扫描局域网设备?

wen 实用脚本 1

本文目录导读:

怎样用脚本自动扫描局域网设备?

  1. 使用 Python 脚本扫描
  2. 使用 Bash 脚本(Linux/Mac)
  3. 使用 nmap 工具(推荐)
  4. 综合扫描脚本
  5. 使用说明
  6. 注意事项

我来介绍几种常用的局域网设备扫描方法,包括简单的脚本和工具。

使用 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()

使用说明

  1. 权限要求:某些操作可能需要root/管理员权限
  2. 性能优化:使用线程池并行扫描可大大加快速度
  3. 结果输出:支持控制台输出和JSON导出
  4. 跨平台:脚本兼容Windows/Linux/Mac

注意事项

  • ⚠️ 仅在自己的网络中进行扫描
  • 扫描前确认有权限进行网络探测
  • 某些网络设备和安全软件可能会阻止扫描
  • 企业网络中的扫描可能需要IT部门授权

这些脚本可以实现基本的局域网设备扫描,根据具体需求选择合适的方案即可。

抱歉,评论功能暂时关闭!