2013-12-09 269 views
5

我想操作带有RaspberryPi的WiFi加密狗(它就像一个没有内置WiFi的CPU)。我需要编写一个自动扫描WiFi网络的python脚本,并且需要使用已知的SSID和密码自动建立连接。RaspberryPi的python脚本自动连接wifi

这意味着我需要从一个文件提供WiFi网络的密码,剩下的事情就是自动进行扫描和连接。

我从网上读取了一个包含WiFi SSID名称和密码的文件。

我需要编写一个脚本,它扫描并列出当前网络并将其与文件中的SSID进行匹配,并进一步自动创建与此已知网络的连接。

树莓派OS:Rasbian

+0

您的问题不不知何故似乎有道理。你想从网络上获取无线网络的详细信息,然后使用它们连接到无线网络?如果没有互联网连接,你应该怎么做? –

+0

我不确定你需要什么帮助,你是否正在寻找一个Raspberry脚本,它可以自动连接到网络,如果它从扫描当前的WiFi环境?你想写脚本还是想找一个为你做这个的模块? – qrikko

回答

17

wifi是用于扫描和连接到WiFi网络Linux上的Python库。您可以使用它扫描并连接到无线网络。

它没有任何自动连接到网络的内置支持,但您可以轻松编写脚本来完成此操作。这里有一个如何做到这一点的基本想法的例子。

#!/usr/bin/python 
from __future__ import print_function 

from wifi import Cell, Scheme 

# get all cells from the air 
ssids = [cell.ssid for cell in Cell.all('wlan0')] 

schemes = list(Scheme.all()) 

for scheme in schemes: 
    ssid = scheme.options.get('wpa-ssid', scheme.options.get('wireless-essid')) 
    if ssid in ssids: 
     print('Connecting to %s' % ssid) 
     scheme.activate() 
     break 

我只是写了它,它似乎工作。就这样你知道,我写了无线网络库。如果你想让我把这个功能添加到图书馆,我可以。

+2

嘿@rockymeza,我认为autoconnect功能可能很棒,并且对于覆盆子pi用户尤其有帮助! – dalanmiller

+0

@rockymeza我不明白如何使用它?我不需要生成密码?因为当我使用你的代码我的WiFi仍然没有连接。 Thankyou –

+0

在'schemes = list(Scheme.all())'的输出中是否有任何东西?如果不是,那是因为首先你必须创建方案。有关更多信息,请参阅http://wifi.readthedocs.org/en/latest/scanning.html#connecting-to-a-network。 – rockymeza

1

这是上面rockymeza答案的猴子补丁,因此Scheme将使用/etc/wpa_supplicant/wpa_supplicant.conf文件而不是/ etc/network/interfaces文件。我无法让他的Scheme类在我的pi3上工作,因为它似乎只是为每个网络添加了wlan0-SSIDname给/ etc/network/interfaces文件,并且没有映射或任何东西来告诉它ifup wlan0-SSID名与'wlan0'关联。

import re 
from wifi import Cell, Scheme 
import wifi.subprocess_compat as subprocess 
from wifi.utils import ensure_file_exists 

class SchemeWPA(Scheme): 

    interfaces = "/etc/wpa_supplicant/wpa_supplicant.conf" 

    def __init__(self, interface, name, options=None): 
     self.interface = interface 
     self.name = name 
     self.options = options or {} 

    def __str__(self): 
     """ 
     Returns the representation of a scheme that you would need 
     in the /etc/wpa_supplicant/wpa_supplicant.conf file. 
     """ 

     options = ''.join("\n {k}=\"{v}\"".format(k=k, v=v) for k, v in self.options.items()) 
     return "network={" + options + '\n}\n' 

    def __repr__(self): 
      return 'Scheme(interface={interface!r}, name={name!r}, options={options!r}'.format(**vars(self)) 
    def save(self): 
     """ 
     Writes the configuration to the :attr:`interfaces` file. 
     """ 
     if not self.find(self.interface, self.name): 
      with open(self.interfaces, 'a') as f: 
       f.write('\n') 
       f.write(str(self))   

    @classmethod 
    def all(cls): 
     """ 
     Returns an generator of saved schemes. 
     """ 
     ensure_file_exists(cls.interfaces) 
     with open(cls.interfaces, 'r') as f: 
      return extract_schemes(f.read(), scheme_class=cls) 
    def activate(self): 
     """ 
     Connects to the network as configured in this scheme. 
     """ 

     subprocess.check_output(['/sbin/ifdown', self.interface], stderr=subprocess.STDOUT) 
     ifup_output = subprocess.check_output(['/sbin/ifup', self.interface] , stderr=subprocess.STDOUT) 
     ifup_output = ifup_output.decode('utf-8') 

     return self.parse_ifup_output(ifup_output) 
    def delete(self): 
     """ 
     Deletes the configuration from the /etc/wpa_supplicant/wpa_supplicant.conf file. 
     """ 
     content = '' 
     with open(self.interfaces, 'r') as f: 
      lines=f.read().splitlines() 
      while lines: 
       line=lines.pop(0) 

       if line.startswith('#') or not line: 
        content+=line+"\n" 
        continue 

       match = scheme_re.match(line) 
       if match: 
        options = {} 
        ssid=None 
        content2=line+"\n" 
        while lines and lines[0].startswith(' '): 
         line=lines.pop(0) 
         content2+=line+"\n" 
         key, value = re.sub(r'\s{2,}', ' ', line.strip()).split('=', 1) 
         #remove any surrounding quotes on value 
         if value.startswith('"') and value.endswith('"'): 
          value = value[1:-1] 
         #store key, value 
         options[key] = value 
         #check for ssid (scheme name) 
         if key=="ssid": 
          ssid=value 
        #get closing brace   
        line=lines.pop(0) 
        content2+=line+"\n" 

        #exit if the ssid was not found so just add to content 
        if not ssid: 
         content+=content2 
         continue 
        #if this isn't the ssid then just add to content 
        if ssid!=self.name: 
         content+=content2 

       else: 
        #no match so add content 
        content+=line+"\n" 
        continue 

     #Write the new content 
     with open(self.interfaces, 'w') as f: 
      f.write(content)  

scheme_re = re.compile(r'network={\s?') 


#override extract schemes 
def extract_schemes(interfaces, scheme_class=SchemeWPA): 
    lines = interfaces.splitlines() 
    while lines: 
     line = lines.pop(0) 
     if line.startswith('#') or not line: 
      continue 

     match = scheme_re.match(line) 
     if match: 
      options = {} 
      interface="wlan0" 
      ssid=None 

      while lines and lines[0].startswith(' '): 
       key, value = re.sub(r'\s{2,}', ' ', lines.pop(0).strip()).split('=', 1) 
       #remove any surrounding quotes on value 
       if value.startswith('"') and value.endswith('"'): 
        value = value[1:-1] 
       #store key, value 
       options[key] = value 
       #check for ssid (scheme name) 
       if key=="ssid": 
        ssid=value 

      #exit if the ssid was not found 
      if ssid is None: 
       continue 
      #create a new class with this info 
      scheme = scheme_class(interface, ssid, options) 

      yield scheme 

要创建方案,只是这样做:

scheme=SchemeWPA('wlan0',cell.ssid,{"ssid":cell.ssid,"psk":"yourpassword"}) 

你的/ etc /网络/接口文件应该是这样的,或类似:

# interfaces(5) file used by ifup(8) and ifdown(8) 

# Please note that this file is written to be used with dhcpcd 
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf' 
# Include files from /etc/network/interfaces.d: 
source-directory /etc/network/interfaces.d 

auto lo 
iface lo inet loopback 

iface eth0 inet manual 

allow-hotplug wlan0 
iface wlan0 inet manual 
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf 

iface default inet dhcp 

allow-hotplug wlan1 
iface wlan1 inet manual 
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf