搜索局域网在线 IPv4 的 Python3 脚本

要解决的痛点:

(1)局域网内有需要通过网络访问的终端,但不知道其 IP 地址

(2)局域网内需要通过网络访问的终端,其 IP 通过动态主机配置协议 DHCP 配置,启动后发生了变化,但不知道变化后的 IP。

本工具的作用:

扫描所在局域网内所有可以 ping 通的 IP,缩小连接试探范围。

本工具依赖:

Python 3.8以上。更低的 Python 版本未经过测试,不保证可以工作。

只依赖 Python3 的内置包。

适用于 Windows 和 Linux。

本工具特性:

自动获取本机 IPv4 地址,并根据所获取的本机 IPv4 地址,扫描前三段相同的可以 ping 通的 IP 地址(如有其它需求,请自行修改)。

本机可以有多个 IPv4 地址,处于相同网段的 IPv4 地址在扫描过程中会自动合并。

扫描过程启用了多线程,几秒钟可以出结果。

*** 避免在 Windows 下用 IDLE 运行本工具,这种方式运行将弹出非常多的命令行终端,速度非常慢 ***

本工具使用方法:

复制下面的脚本内容,存储到名为 LanScan.py 的文件中。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
LAN Fast Scanner

Created on Tue Aug  6 16:13:26 2019

@author: farman
"""

import os
import sys
import threading
import subprocess


def get_local_ipv4_linux():
    out_bytes = subprocess.check_output(['ifconfig'])
    local_ip = []

    for line in out_bytes.decode().split('\n'):
        if     line.find('inet6')     == -1 \
           and line.find('inet')      >  -1 \
           and line.find('127.0.0.1') == -1:
            line = line[:line.find('netmask')]
            line = line.strip().split()[1]
            local_ip.append(line)
            
    return local_ip


def get_local_ipv4_windows():
    out_bytes = subprocess.check_output(['ipconfig'])
    local_ip = []

    for line in out_bytes.decode("GB2312").split('\n'):
        if line.count('IPv4'):
            line = line[line.find(':') + 1 :]
            line = line.strip().rstrip()
            local_ip.append(line)
            
    return local_ip


def get_local_ipv4():
    return get_local_ipv4_linux() if sys.platform == "linux" else get_local_ipv4_windows()

if 0:
    x = get_local_ipv4()
    print(x)


def merge_ip_list(ip_list):
    merged_ip_list = []
    
    for ip in ip_list:
        ip = ip[: ip.rfind('.')]
        
        if ip not in merged_ip_list:
            merged_ip_list.append(ip)
        
    return merged_ip_list

if 0:
    x = get_local_ipv4()
    y = merge_ip_list(x)
    print(y)


def my_ping_linux(a, b, c, d):
    '''
    Ping a given ip, and return the result.
    
    The IP address to be pinged is "a.b.c.d".
    '''
    ip = '%s.%s.%s.%s'%(a, b, c, d)
    command = 'ping %s -c 1 -W 1'%ip
    return ip if not os.system(command) else None


def my_ping_windows(a, b, c, d):
    '''
    Ping a given ip, and return the result.
    
    The IP address to be pinged is "a.b.c.d".
    '''
    ip = '%s.%s.%s.%s'%(a, b, c, d)
    command = 'ping %s -n 1 -w 1'%ip
    return ip if not os.system(command) else None


def my_ping(a, b, c, d):
    return my_ping_linux(a, b, c, d) if sys.platform == 'linux' else my_ping_windows(a, b, c, d)

if 0:
    x = my_ping(192, 168, 4, 1)
    print(x)
    x = my_ping(192, 168, 3, 1)
    print(x)


'''
Module "threading" of python3 is used to accelerate the scan operation.
'''
 
class MyThread(threading.Thread):
    """
    This Class is just for result fetching of threaded function.
    """
    
    def __init__(self, function, args):
        threading.Thread.__init__(self)
        self.function = function
        self.args = args
        
    def run(self):
        self.result = self.function(*self.args)
        
    def get_result(self):
        return self.result


def scan_lan(a, b, c, d_begin=1, d_end=255):
    '''
    Scan LAN neighbours by ping command
    in range from "a.b.c.d_begin" to "a.b.c.d_end"
    with threading method to reduce time consumption of scanning.
    
    input:
        The IP address to be pinged is "a.b.c.d".
    
    outpur:
        list of IP address of active neighbours.
    '''
    threads = [MyThread(my_ping, (a, b, c, d)) for d in range(d_begin, d_end)]
    
    for n in range(len(threads)):
        threads[n].start()
    
    for n in range(len(threads)):
        threads[n].join()
    
    valid_ip = []
    
    for n in range(len(threads)):
        ip = threads[n].get_result()
        
        if ip != None:
            valid_ip.append(ip)
    
    return valid_ip

if 0:
    x = scan_lan(192, 168, 3)
    print(scan_lan(192, 168, 3))


def auto_scan():
    '''
    Auto scan LAN neighbours, return their IP addresses.
    
    Calling this function directly is the right manner to 
    get IP addresses of LAN neighbouts 
    because it's convinient and so comfort:)
    '''
    local_ip_list = get_local_ipv4()
    valid_ip_list = []
    
    if len(local_ip_list):
        local_ip_list_of_former_3_segments = merge_ip_list(local_ip_list)
    
        for ip in local_ip_list_of_former_3_segments:
            [a, b, c] = ip.split('.')
            valid_ip_list += scan_lan(a, b, c)

    return local_ip_list, valid_ip_list


def show_result(local_ip_list, valid_ip_list):
    os.system("clear" if sys.platform == 'linux' else 'cls')
    
    print('\n\nLAN IP Address Scanner')
    print('-'*40)
    print(' '*22, 'Farman@2023.05.23\n')
    
    print('Valid Network Address%s found : %s'%(
        '' if len(valid_ip_list)< 2 else 'es',
        len(valid_ip_list)))
    
    print('-'*40)
    
    count = 0
    
    for valid_ip in valid_ip_list:
        a, b, c, d = valid_ip.split('.')
        ip_segments = ['0' * (3 - len(seg)) + seg for seg in valid_ip.split('.')]
        print('    No.%03d - %s %s'%(count+1, '.'.join(ip_segments), '[LOCAL]' if valid_ip in local_ip_list else ''))
        count += 1
    
    input("\nPress 'Enter' to exit ...")
    return

#------------------------------------------------------------------------------

if __name__ == '__main__':
    local_ip_list, valid_ip_list = auto_scan()
    show_result(local_ip_list, valid_ip_list)

Windows 命令行调用

python LanScan.py

Linux 终端调用

python3 LanScan.py

Enjoy it!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值