Linux 服务器: CentOS 7
firefox 浏览器版本:Mozilla Firefox 68.5.0esr
建议: 在安装之前可以在linux 服务器上新建一个项目文件夹,以便后续存放文件和日志信息 (本人创建的项目文件夹名 auto_connect)
下载之前先要查看服务器上firefox 浏览器的版本, 并且下载对应版本的selenium 和geckodriver
在服务器终端输入命令
firefox -V
firefox 浏览器版本与selenium 和 geckodriver 版本对应表
geckodriver 下载链接
本人选择的selenium 版本是3.141.0 ; geckodriver 版本是0.29.0
最好在conda 环境下下载, 需要先激活自己的conda 环境
# 安装selenium命令, 在conda 环境下安装
pip install selenium=3.141.0
# 查看安装的selenium版本
import selenium
print(help(selenium))
# 1. 下载geckodriver(可以先从本地下载,然后上传到服务器)
wget https://github.com/mozilla/geckodriver/releases/download/v0.29.0/geckodriver-v0.29.0-linux64.tar.gz
# 2. 解压, 解压后将 geckodriver.exe 放在新建的项目文件夹auto_connect下
tar --xvzf geckodriver-v0.26.0-linux64.tar.gz
# 3. 修改权限
chmod +x geckodriver
# 4. 转移,将 geckodriver 复制到 /usr/bin /usr/local/bin 和python.exe 的目录下
# 复制到 /usr/bin
sudo cp geckodriver /usr/bin
# 复制到 /usr/local/bin
sudo cp geckodriver /usr/local/bin
# 复制到与python.exe 同目录下,由于本人的环境conda 环境,所以复制到conda 环境下与python.exe 同目录下
sudo cp geckodriver /home/user1/anaconda3/envs/自己的环境名/bin/
在新建的auto_connect文件夹下新建auto_connect.py 文件
每次重连的打印信息都会被保存进日志文件auto_connect_log.txt
在conda 环境下运行
在编写脚本之前需要准备的信息:
1. 校园网登录的网址
2. 校园网登录的账号和密码
3. 校园网登陆网页中填写账号、密码和点击登录按钮的相应组件
完整代码
from selenium import webdriver
from selenium.webdriver import FirefoxOptions
from bs4 import BeautifulSoup
import time
import requests
username_str = "*******" # 你的校园网登陆用户名
password_str = "********" # 你的校园网登陆密码
can_connect = True
def login():
profile = webdriver.FirefoxProfile()
# 禁止下载图片,根据情况使用
profile.set_preference("permissions.default.image", 2)
# 禁用浏览器缓存
profile.set_preference("network.http.use-cache", False)
profile.set_preference("browser.cache.memory.enable", False)
profile.set_preference("browser.cache.disk.enable", False)
profile.set_preference("browser.sessionhistory.max_total_viewers", 3)
profile.set_preference("network.dns.disableIPv6", True)
profile.set_preference("Content.notify.interval", 750000)
profile.set_preference("content.notify.backoffcount", 3)
# 有的网站支持 有的不支持 2 35 profile.set_preference("network.http.pipelining", True)
profile.set_preference("network.http.proxy.pipelining", True)
profile.set_preference("network.http.pipelining.maxrequests", 32)
# print(getCurrentTime(), '2.0 trying to connect')
with open("auto_connect_log.txt", "a+") as f:
f.write("\n" + getCurrentTime() + " 0. trying to connect Internet")
# 2.1 配置opt
opts = FirefoxOptions()
opts.add_argument("--headless")
driver = webdriver.Firefox(options=opts, firefox_profile=profile)
try:
# print(getCurrentTime(), '2.1 driver get sucessfully')
with open("auto_connect_log.txt", "a+") as f:
f.write("\n" + getCurrentTime() + " 1. driver init successful")
driver.get("***********") # 你的校园网登陆地址
driver.refresh()
# print(getCurrentTime(), '2.2 get url sucessful')
with open("auto_connect_log.txt", "a+") as f:
f.write("\n" + getCurrentTime() + " 2. the diver init and address insert successful")
# 2.2 获取账号、密码、登录按钮组件
# print(driver.find_elements_by_name("DDDDD"))
# print(driver.find_elements_by_name("upass"))
# print(driver.find_elements_by_name("0MKKey"))
username_input = driver.find_elements_by_name("DDDDD")[1] # 校园网登陆用户名的输入控件ID, 浏览器上右键查看网页源代码查询
password_input = driver.find_elements_by_name("upass")[1] # 校园网登陆密码的输入控件ID, 浏览器上右键查看网页源代码查询
login_button = driver.find_elements_by_name("0MKKey")[1] # 校园网登陆连接的点击控件ID, 浏览器上右键查看网页源代码查询
# print(getCurrentTime(), '2.3 username and password get suceessful')
with open("auto_connect_log.txt", "a+") as f:
f.write("\n" + getCurrentTime() + " 3. the account password and loginButton get successful")
# 2.3 发送账号、密码、并点击登录
username_input.send_keys(username_str)
# print(getCurrentTime(), '2.4 successsfully input name')
password_input.send_keys(password_str)
# print(getCurrentTime(), '2.5 successsfully input pass')
login_button.click()
# print(getCurrentTime(), '2.6 successsfully click button')
# print(getCurrentTime(), '2.7 connect successfully')
with open("auto_connect_log.txt", "a+") as f:
f.write("\n" + getCurrentTime() + " 4. Connect successfully \n")
except Exception as e:
print(getCurrentTime(), e)
# 登陆错误
print(getCurrentTime(), "2.-1 Error Login")
finally:
driver.quit()
#获取当前时间
def getCurrentTime():
return time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time()))
#判断当前是否可以连网
def handler():
try:
global can_connect
can_connect = False # 默认判断连接为失败状态
# 需要设置timeout是因为断网时request会堵住程序, 设置timeout后最多等待10s,如果没有request成功, can_connect为False
baidu_request = requests.get("http://www.baidu.com", timeout=10)
if(baidu_request.status_code==200):
# print(getCurrentTime(), "1.1 status = 200")
baidu_request.encoding = 'utf-8'
baidu_request_bsObj = BeautifulSoup(baidu_request.text, 'html.parser')
baidu_input = baidu_request_bsObj.find(value="百度一下")
if baidu_input==None:
return False
can_connect = True # 只有可以request 到百度的网址,并且页面中含有“百度一下”这几个字符,才判断连接成功
return True
else:
print(getCurrentTime(), '1.2 Offline')
return False
except:
print('error')
return False
#主函数
def main():
# 连接校园网脚本开始运行
print(getCurrentTime(), u"Hi, The Script of auto_connect start to run")
# time.sleep(600)
while True:
# print(getCurrentTime(), "1. checking the internet")
handler() # 1. 测试是否有网
global can_connect
# print(can_connect)
if not can_connect:
# 断网了
with open("auto_connect_log.txt","a+") as f:
f.write("\n" + getCurrentTime() + " The Internet disconnect, and I am trying to connect it....")
# print(getCurrentTime(), "2. The Internet disconnect, and I am trying to connect it....")
login() # 2. 尝试连接
else:
# 正常
# print(getCurrentTime(), "All is normal.....")
time.sleep(300)
main()
自动连接程序运行了一周都是正常的,但是突然出现这个问题
使用top 命令查看CPU占有率
top 命令详解
top -bn 1 -i -c
可以看到有很多firefox 进程, 进一步查看火狐浏览器进程
ps -aux|grep firefox
删除所有firefox 进程, 重新运行自动连接脚本
pkill firefox
自动连接脚本成功运行一周,但是突然报错,driver.get(url) 超时, 无法自动连接
查看 auto_connect 文件夹占有的内存大小, 发现竟然占用21G
查看文件夹占有大小
du -h --max-depth=1
解决办法:
1. 定期手动删除服务器上的auto_connect文件夹, 然后从本地重新上传
2. 配置页面加载优化和浏览器缓存
profile = webdriver.FirefoxProfile()
# 禁止下载图片,根据情况使用
profile.set_preference("permissions.default.image", 2)
# 禁用浏览器缓存
profile.set_preference("network.http.use-cache", False)
profile.set_preference("browser.cache.memory.enable", False)
profile.set_preference("browser.cache.disk.enable", False)
profile.set_preference("browser.sessionhistory.max_total_viewers", 3)
profile.set_preference("network.dns.disableIPv6", True)
profile.set_preference("Content.notify.interval", 750000)
profile.set_preference("content.notify.backoffcount", 3)
# 有的网站支持 有的不支持 2 35 profile.set_preference("network.http.pipelining", True)
profile.set_preference("network.http.proxy.pipelining", True)
profile.set_preference("network.http.pipelining.maxrequests", 32)
driver = webdriver.Firefox(options=opts, firefox_profile=profile)
3. 每次driver.get(url)刷新窗口
driver.get("***************") # 你的校园网登陆地址
driver.refresh()
HTTPConnectionPool(host=‘www.baidu.com’, port=80): Max retries exceeded with url: / (Caused by NewConnectionError(‘
: Failed to establish a new connection: [Errno -2] Name or service not known’))
handler() 函数中通过request.get(url) 与 baidu 建立 TCP 连接,默认为keep-alive,即连接一次,传输多次,然而在多次访问后不能结束并回到连接池中,导致不能产生新的连接