【selenium】Windows平臺下使用python自動登陸網關 (更新至 v1.1.0)

0x00 前言

所裏開啓了兩步驗證與二級加密(就不說是哪裏了);
以前的auto_login用不了了,所以嘗試着有沒有什麼新法子;
看到一個用 Phantomjs + Selenium 的解決方案,着手試試看好了。

文中涉及的login腳本解決方案參照自如下Github:
https://github.com/gongshijun/ict_autoconnect

由於配置過於坎坷,所以個人直接做了個簡化方案,
嫌看的麻煩的或者想要直接使用的可以直接跳轉這裏
更新(Thx for lhw446):嫌配置麻煩的可以用這個單文件版

0x01 獲取登陸腳本

可以從Github倉庫上直接clone到本地

D:\Github>git clone https://github.com/gongshijun/ict_autoconnect.git
Cloning into 'ict_autoconnect'...
remote: Counting objects: 29, done.
remote: Total 29 (delta 0), reused 0 (delta 0), pack-reused 29
Unpacking objects: 100% (29/29), done.
Checking connectivity... done.

也可以下載zip壓縮包到本地解壓
https://github.com/gongshijun/ict_autoconnect/archive/master.zip

本人放在了D:\Github目錄下,下文中均默認設爲此目錄中進行介紹。

0x02 環境配置

python

唔……我確實真的有仔細考慮要不要把python放進環境需求的一部分……
想了想……嗯,該說的還是要說的

  • Windows cmd (Win+R 輸入cmd然後回車)
  • python2.7
  • 如果您想做成EXE格式的程序,請同時配有python3.3或者python3.4
    • (作者大大炫技結果不小心造成了複雜度的提升)

PhantomJS

https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-windows.zip
windows平臺的各位把這個下載下來之後解壓放在剛剛的目錄中,比如我解壓後放在

 D:\Github\ict_autoconnect 的目錄

2017/08/29  13:38    <DIR>          .
2017/08/29  13:38    <DIR>          ..
2017/08/29  13:35             1,266 .gitignore
2017/08/29  13:35             1,005 common.py
2017/08/29  13:35    <DIR>          js
2017/08/29  13:35            11,558 LICENSE
2017/08/29  13:35             2,141 login.py
2016/01/25  06:17    <DIR>          phantomjs-2.1.1-windows  # <= 這裏
2017/08/29  13:35             1,237 README.md
2017/08/29  13:35               403 setup.py
2017/08/29  13:40                40 user.conf

selenium

# 直接安裝,不過可能會連接超時或者很慢
C:\Users\Work>pip install selenium
Collecting selenium
  Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.python.org', port=443): Read timed out. (read timeout=15)",)'

# 如果pypi源下載不便,可以選擇用國內源下載,記得加上trusted-host參數
# 這裏我用豆瓣的了,當然用清華、阿里之類的都是可以的
C:\Users\Work>pip install -i http://pypi.douban.com/simple/ selenium --trusted-host pypi.douban.com
Installing collected packages: selenium
Successfully installed selenium-3.5.0

0x03 準備工作

user.conf (設置用戶名&密碼)

conf文件裏寫好自己的用戶名密碼就好啦

username = YOUR_USERNAME
password = YOUR_PASSWORD

setup.py(輸出爲可執行文件,python 3.3/3.4 可選)

這個setup.py的作用是將python腳本做成exe可執行文件,
然而其中帶有的py2exe模塊是py3.3以上纔可以使用的包,所以如果想做成exe格式的執行文件的話,
請自備py2與py3兩個版本的python

接下來是本人的心路歷程

# 首先我們來看看這個setup.py
D:\Github\ict_autoconnect>python setup.py
Traceback (most recent call last):
  File "setup.py", line 10, in <module>
    import py2exe
ImportError: No module named py2exe

# 好嘛,沒有我就去裝唄
D:\Github\ict_autoconnect>pip install py2exe
Collecting py2exe
  Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.python.org', port=443): Read timed out. (read timeout=15)",)': /simple/py2exe/

# 哦忘記了……
D:\Github\ict_autoconnect>pip install -i http://pypi.douban.com/simple/ py2exe --trusted-host pypi.douban.com
Collecting py2exe
    RuntimeError: This package requires Python 3.3 or later

# WHAT???
# 轉爲 python3.6.0 後(請善用activate)

# 對了轉成python3之後別忘了剛剛裝的selenium
D:\Github\ict_autoconnect>pip install -i http://pypi.douban.com/simple/ selenium --trusted-host pypi.douban.com
Installing collected packages: selenium
Successfully installed selenium-3.5.0

# 可以,能裝py2exe了
D:\Github\ict_autoconnect>pip install -i http://pypi.douban.com/simple/ py2exe --trusted-host pypi.douban.com
Installing collected packages: py2exe
Successfully installed py2exe-0.9.2.2

# ......
D:\Github\ict_autoconnect>python setup.py
  yield "store", (names[oparg],)
IndexError: tuple index out of range

細心的我去stackoverflow查了一下
傳送門:python-indexerror-tuple-index-out-of-range-when-using-py2exe
The bytecode often changes in small ways from version to version that could break even Python 3.5 (given only 3.3 and 3.4 support is claimed explicitly), but 3.6 is 100% guaranteed to fail.

簡單解釋一下,py2exe這個東西可行的版本極爲狹窄,py3.3或3.4纔可以使用:(以下說明來自知乎 @劉智敏)
把python回退到3.4之後,這個問題得到解決。根據Python3.5的API變動說明,初步判斷問題原因是 generators 在3.5之後的屬性有變化,而 yield 的實現用到了 generator(瞭解很淺,如有誤請指正)。正好py2exe支持的最高版本爲py3.4 。

# 怒開一個新的python3.3環境 
$ conda create -n python3.3 numpy python=3.3 # numpy可選,我個人裝啥都喜歡帶個numpy
$ activate python3.3

(python3.3) D:\Github\ict_autoconnect>pip install -i http://pypi.douban.com/simple/ py2exe --trusted-host pypi.douban.com

(python3.3) D:\Github\ict_autoconnect>pip install -i http://pypi.douban.com/simple/ selenium --trusted-host pypi.douban.com

(python3.3) D:\Github\ict_autoconnect>python setup.py
running py2exe

  5 missing Modules
  ------------------
? netbios                             imported from uuid
? readline                            imported from cmd, code, pdb
? win32api                            imported from platform
? win32con                            imported from platform
? win32wnet                           imported from uuid
Building 'dist\login.exe'.
Building shared code archive 'dist\library.zip'.
Copy c:\programdata\anaconda3\envs\python3.3\python33.dll to dist
Copy C:\ProgramData\Anaconda3\envs\python3.3\DLLs\unicodedata.pyd to dist\unicodedata.pyd
Copy C:\ProgramData\Anaconda3\envs\python3.3\DLLs\_lzma.pyd to dist\_lzma.pyd
Copy C:\ProgramData\Anaconda3\envs\python3.3\DLLs\_ctypes.pyd to dist\_ctypes.pyd
Copy C:\ProgramData\Anaconda3\envs\python3.3\DLLs\_bz2.pyd to dist\_bz2.pyd
Copy C:\ProgramData\Anaconda3\envs\python3.3\DLLs\_hashlib.pyd to dist\_hashlib.pyd
Copy C:\ProgramData\Anaconda3\envs\python3.3\DLLs\_socket.pyd to dist\_socket.pyd
Copy C:\ProgramData\Anaconda3\envs\python3.3\DLLs\_ssl.pyd to dist\_ssl.pyd
Copy C:\ProgramData\Anaconda3\envs\python3.3\DLLs\pyexpat.pyd to dist\pyexpat.pyd
Copy C:\ProgramData\Anaconda3\envs\python3.3\DLLs\select.pyd to dist\select.pyd
Copy DLL C:\ProgramData\Anaconda3\envs\python3.3\MSVCR100.dll to dist\

library.zip

$ python setup.py搞定之後,就會發現目錄下多了幾個文件夾,進入目錄js/,把裏面的兩個js文件放進dist/library.zip裏的selenium/webdriver/remote裏。

test

然後這個dist文件夾就相當於一個你本人定製的release了,那個login.exe就可以直接使用了(基於之前user.conf裏的帳號與密碼)

 D:\Github\ict_autoconnect\dist 的目錄

2017/08/29  14:35    <DIR>          .
2017/08/29  14:35    <DIR>          ..
2017/08/29  14:35         4,970,261 library.zip
2017/08/29  14:34            33,280 login.exe
2010/03/18  22:36           827,728 MSVCR100.dll
2014/03/10  00:35           168,960 pyexpat.pyd
2017/08/29  14:34         3,927,552 python33.dll
2014/03/10  00:35            10,752 select.pyd
2014/03/10  00:35           762,368 unicodedata.pyd
2014/03/10  00:35            62,464 _bz2.pyd
2014/03/10  00:35           108,032 _ctypes.pyd
2014/03/10  00:35         1,065,472 _hashlib.pyd
2014/03/10  00:35           135,168 _lzma.pyd
2014/03/10  00:35            51,712 _socket.pyd
2014/03/10  00:35         1,710,080 _ssl.pyd

0x04 人生苦短,善用python

哇這麼一大堆東西怕是看着看着都要睡着了喲……
(有空回來做個簡易版,就算不簡易至少也要把那麼多指令整合到一個shell腳本里……)

CDLogin for Windows/ 自制簡易版解決方案使用方法
1) 到百度網盤下載:( 當前最新版本爲 Release v1.0.1 )
=> 公有傳送門 無需密碼
=> 密碼傳送門 密碼:hf3w

2) 解壓到目錄,然後使用cmd進入該目錄,安裝selenium:
$ pip install -i http://pypi.douban.com/simple/ selenium --trusted-host pypi.douban.com

3) 把user.conf裏的帳號密碼改成你們自己的!
請務必改成你們自己的,即便是爲了穩定性

4) 雙擊打開login.py
推薦把.py文件的默認打開方式設置爲python.exe,
這樣就可以直接運行而不需要再包一層shell來跑$ python login.py

5) 如果正常運轉了,發送到桌面快捷方式,然後把這個快捷方式放進你的啓動文件夾裏即可
一般來說是個叫Startup或者啓動的目錄

6) 嘗試着爲多平臺努力中
爲了程序容量不能過於龐大,就不把各平臺的PhantomJS都放進去了,如果你不是windows平臺,
請前往 http://phantomjs.org/download.html 下載你自己平臺的PhantomJS,
解壓之後在裏面找到PhantomJS放在和login.py同目錄下即可。

0x05 主文件SourceCode

#coding=utf8
# ========================================================
#   Copyright (C) 2017 All rights reserved.
#   
#   filename : CDLogin.py
#   author   : [email protected]
#   date     : 2017-08-29
#   desc     : Auto_Login Test
# ======================================================== 

import os
import time
import selenium
from selenium import webdriver

import platform
# "Windows" or "Linux"
OS_TYPE = platform.system()

def auto_connect(un, pw):
    print('open a phantomJS browser...\n')
    try:
        browser = webdriver.PhantomJS()
    except selenium.common.exceptions.WebDriverException as e:
        # Message: 'phantomjs' executable needs to be in PATH.
        print("Current Version only contains Windows PhantomJS.")
        print("You need phantomJS for your own platform as <%s>" % OS_TYPE)
        print("Please visit http://phantomjs.org/download.html for downloading")
        print("Download and unzip and find PhantomJS, copy it beside this python file.")
        print("For further info, visit http://blog.csdn.net/okcd00/article/details/77677326#t10")
        os.system('pause')
        exit()

    browser.get('http://159.226.39.22')

    username, password = un, pw

    browser.find_element_by_id('username').send_keys(username)
    browser.find_element_by_id('password').send_keys(password)
    #browser.find_element_by_id('button').click()
    browser.find_element_by_id('form2').submit()

    print('waiting 10s for posting...')
    time.sleep(10)
    browser.close()

def read_conf():
    un = ''
    pw = ''
    ps = ''
    try:
        with open('user.conf', 'r') as file:
            for line in file.readlines():
                line = line.strip()
                if line == '':
                    continue
                if line[0] == '#':
                    continue
                if line.split('=')[0].strip() == 'username':
                    un = line.split('=')[1].strip()
                elif line.split('=')[0].strip() == 'password':
                    pw = line.split('=')[1].strip()
                elif line.split('=')[0].strip() == 'pingsite':
                    ps = line.split('=')[1].strip()
                else:
                    print('user.conf is a error format. \n')
    except IOError as e:
        print('cannot read user.conf file--' + str(e) + ', please create user.conf file. \n')
    return un, pw, ps

def is_connect(ps):
    if OS_TYPE == 'Windows':
        flag = os.system('ping ' + ps)
    elif OS_TYPE == 'Linux':
        flag = os.system('ping -c 3 ' + ps)
    if flag == 0:
        return True
    return False

def con_connect(un, pw, ps):
    if is_connect(ps):
        return 1
    else:
        auto_connect(un, pw)
        if is_connect(ps):
            print('\nConnect internet success.\n')
        else:
            print('\nConnect internet Failed.\n')
        return 1


if __name__ == '__main__':
    print("starting...")
    os.system('MODE con: COLS=128 LINES=32 & TITLE Welcome to CDLogin')

    from logo import show_logo
    # show_logo()
    os.system('cls')

    time.sleep(1)
    os.system("color 0A")
    os.system('MODE con: COLS=64 LINES=16 & TITLE CD_Auto_Login is working')

    un, pw, ps = read_conf()

    while 1:
        print('=== current time ===')
        os.system("DATE /T & TIME /T")

        print('If you want to stop, input Ctrl+C to break.')
        con_connect(un, pw, ps)

        print('\nNext check in 10 mins ...\n')
        time.sleep(10*60) #Test
        os.system('cls')

0xFF 單文件可行版本

#coding=utf8
import os
import time
import random
import urllib
import urllib2
import platform
import cookielib

uname = "test" # Change to your username
passwd = "123456" # Change to your password
ip = "10.63.0.222" # Modify this to your own ip 
interval_time = 5*60


def login(uname, passwd):
    cj = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
    opener.addheaders = [('User-agent','Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)')]
    urllib2.install_opener(opener)
    data = {
        "action": "login",
        "username": uname,
        "password": passwd,
        "ac_id": 1,
        "user_ip": ip,
        "ip": ip,
        "nas_ip": '',
        "user_mac": '',
        "save_me": 0,
        "type": 1,
        "n": 100,
        "ajax": 1
    }
    req = urllib2.Request("http://159.226.39.22/include/auth_action.php", urllib.urlencode(data))
    req.add_header("Referer","http://159.226.39.22/")
    try:
        resp = urllib2.urlopen(req)
        res = resp.read()
        print res
        if 'login_ok' in res:
            return True
        else:
            return False
    except:
        print 'log in error'
        return False


def logout(uname, passwd):
    cj = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
    opener.addheaders = [('User-agent','Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)')]
    urllib2.install_opener(opener)
    data = {
        "action": "logout",
        "username": uname,
        "password": passwd,
        "ajax": 1
    }
    req = urllib2.Request("http://159.226.39.22/include/auth_action.php", urllib.urlencode(data))
    req.add_header("Referer","http://159.226.39.22/")
    try:
        resp = urllib2.urlopen(req)
        res = resp.read()
        print res
        if "網絡已斷開" in res or "未曾連接到網絡" in res:
            return True
        else:
            return False
    except:
        print 'log out error'
        return False


def internet_on():
    os_type = platform.system()
    if os_type == "Windows":
        flag = os.system('ping www.baidu.com')
    else:
        flag = os.system('ping -c 3 -t 3 www.baidu.com')
    return flag == 0


def logout_login():
    if logout(uname, passwd):
        print 'logout at: ', time.asctime()
        time.sleep(5)
        if login(uname, passwd):
            print 'login at: ', time.asctime()
        else:
            print 'login fails at: ', time.asctime()
    else:
        print 'logout fails at: ', time.asctime()


if __name__ == '__main__':
    if uname == "lihongwei_test":
        print "please set username, password and ip!"
    else:
        while True:
            if not internet_on():
                logout_login()
            time.sleep(interval_time)

UpdateLog

[2017/09/04] ver 1.1.0 (Author: @lhw446, Original: @cyx)
+ Add single file script.

[2017/08/29] ver 1.0.1 (Feat: @lhw446)

  • Add guide for downloading and setting phantomJS
  • Add available platforms (MAC platform as Linux, maybe Darwin)

[2017/08/29] ver 1.0.0 (Feat: @gongshijun)

  • Basic function for auto_login for ICT
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章