文章目录
- 安装必要环境
- linux环境配置
- 基本的使用
- 创建浏览器控制
- 访问网页
- 获取元素
- By
- 等待浏览器相应
- 元素交互
- 网页游戏的挂载
- 服务器程序不挂断
安装必要环境
- 安装selenium
pip install selenium
- 安装浏览器 这里我使用自带的Edge浏览器
- 安装浏览器driver 根据自己浏览器的版本,去下载Edgedriver,只需要前面的大版本一致就可以,但是还是尽量满足所有的版本一致比较好EdgeDriver所有版本
- 环境变量配置 可以将下载的degedriver.exe文件放到自己的python文件夹中,或者将degedriver.exe的父文件夹加入到系统的path中,这样就可以运行
linux环境配置
我的服务器是ubuntu19 对于linux应该采用chrome浏览器,因为selenium中内置了ChromeOption,可选择关闭浏览器的界面,对于linux的命令式系统是十分契合的
- 下载chromelinux版本的chrome
- 下载chromedriver各种版本的chromedriver
- 安装chrome,解压chormedriver 将下载的浏览器,和driver通过ftp传到服务器上 执行
unzip google-chrome-stable_deb_rpm_....zip
会看到deb和rmp压缩文件,Ubuntu使用deb,centos使用rmp
apt install ./google-chrome-stable_current_amd64.deb
执行
unzip chromedriver_linux64.zip
- 移动chromedriver,增加权限 需要将chrome移动到/usr/bin目录下 执行
mv chormdriver /usr/bin
增加权限
chmod +x /usr/bin/chromedriver
基本的使用
window下
创建浏览器控制
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
driver = webdriver.Edge()
访问网页
driver.get('https://www.baidu.com')
获取元素
- driver.find_element(By,…)
- driver.find_elements(By,…) 最主要的就是这两个方法 前者:当有多个匹配时,返回第一个elementDriver,当未找到时,程序报错中断 后者:返回一个列表,列表内元素都是元素控制器,当未找到时返回一个空列表
By
对于selenium4提倡使用这种By的方式
例如
idFirst = driver.get_element(By.ID, 'first')
等待浏览器相应
因为程序执行是很快的,但是浏览器渲染,解析是耗时的,这就需要程序去等待浏览器渲染出相应的元素才能get到
driver = webdriver.Edge()
driver.implicitly_wait(10)
在创建浏览器控制器时,就可以指定一个等待时间,仅仅在get_element和get_elements时进行停止等待,当超过预定的时间时,才会报错或者返回空列表。当在预定的时间内找到元素时,程序继续运行
元素交互
- send_key() 对于input输入框可以使用elementDriver.send_key(“text”)的方式,向其中输入text文字
- click() 对于button类型的组件可以使用elementDriver.click()来模拟点击操作
- clear() 对于input想要清除其中的输入,可以使用elementDriver.clear()来进行清空 基本上就会用到这三个吧
网页游戏的挂载
最近在玩一个挂机游戏,后台运行还是不错的。匿名修仙 最近嫖了个服务器,准备在上面挂一挂这个网页游戏
linux下运行
from selenium import webdriver
from selenium.webdriver.common.by import By
import urllib.parse as parse
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver.chrome.webdriver import Options
import time
# 针对每个地图提供挂机场所
MAP_MONSTER = {"无极峰": "无极峰兽群", "云天山峰": "珍珠妖鹿群", "落樱山脉": "落樱灵兽群", "通天道": "钻地兽群", "冰神禁地": "守宫人", "林中栈道": "草木野怪"}
USER = {"大号": "username1", "小号": "username2"}
class Niming:
def __init__(self):
self.chrome_option = Options()
# self.chrome_option.add_argument('--no-sandbox')
# self.chrome_option.add_argument('--headless')
# 配置ua
self.chrome_option.add_argument(
'user-agent="Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BLA-AL00 Build/HUAWEIBLA-AL00) '
'AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile '
'Safari/537.36"')
# 启动开发者模式(关闭chrome控制)
self.chrome_option.add_experimental_option("excludeSwitches", ["enable-automation"])
self.chrome_option.add_experimental_option("useAutomationExtension", 'False')
# 关闭保存密码弹窗
self.chrome_option.add_experimental_option("prefs", {"credentials_enable_service": False, "profile"
".password_manager_enabled": False})
self.driver = webdriver.Chrome(options=self.chrome_option)
self.driver.implicitly_wait(8)
self.map = ""
self.options = {}
self.fightObject = {}
self.skills = {}
self.againButton = None
self.messageSpan = None
self.victorCount = None
self.experiencePerMin = None
def __login(self, username):
self.driver.get("https://nimingxx.com")
userName = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div[2]/div/div[1]/div/div['
'1]/div/input')
passWord = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div[2]/div/div[2]/div/div['
'1]/div[1]/input')
login = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div[2]/div/div[4]/button')
userName.send_keys(username)
passWord.send_keys("password")
login.click()
time.sleep(5)
def __setMap(self):
sit = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div/div/div[2]/div/div[2]/div/div['
'2]/div/div/div/div[2]/div[1]/div[2]').get_attribute('innerText')
self.map = sit.split(":")[-1]
print("当前地图:", self.map)
def __setOption(self):
options = self.driver.find_elements(By.XPATH, '//*[@id="app"]/div/div[4]/div/div/div/div[2]/div/div['
'3]/div/div[1]/div/div/div/div')
for option in options:
try:
self.options[option.get_attribute("innerText").split()[0]] = option
except IndexError as e:
pass
def __flush(self):
for i in range(2):
self.driver.execute_script("arguments[0].click()", self.options['修行'])
self.driver.execute_script("arguments[0].click()", self.options['地图'])
def __createTeam(self, mess='', combat='60000', number='5'):
selfCreateButton = self.driver.find_element(By.XPATH, '//*[@id="pane-scene-tab"]/div/div[1]/div/div['
'1]/button[1]/span')
self.driver.execute_script("arguments[0].click()", selfCreateButton)
# 获得三个输入框
input_div = self.driver.find_elements(By.XPATH, '//div[@class="n-popconfirm__body"]/div/div/div')
# 密码输入框
messInput = input_div[0].find_element(By.XPATH, './div/div/div/div/input')
# 战力输入框
combatEffect = input_div[1].find_element(By.XPATH,
'./div/div/div/div/input')
# 成员数选中框
numberDiv = input_div[2].find_element(By.XPATH, 'div/div/div/div')
combatEffect.send_keys(combat)
messInput.send_keys(mess)
self.driver.execute_script("arguments[0].click();", numberDiv)
if number == '5':
baseSelect = self.driver.find_element(By.XPATH, '//div[@class="n-base-select-option '
'n-base-select-option--pending"]')
self.driver.execute_script("arguments[0].click();", baseSelect)
else:
selects = self.driver.find_elements(By.XPATH, '//div[@class="n-base-select-option"]')
self.driver.execute_script("arguments[0].click();", selects[5 - eval(number) - 1])
# 创建按钮
createButton = self.driver.find_element(By.XPATH, '/html/body/div[2]/div/div/div[1]/div[2]/button')
createButton.click()
print("创建队伍成功、密码:{}、战力下限:{}、可进入人数:{}".format(mess, combat, number), end='、')
def __setFightObject(self):
# ActionChains(self.driver).send_keys(Keys.ARROW_DOWN).perform()
self.driver.execute_script("window.scrollBy(0,300)")
fightObject = self.driver.find_elements(By.XPATH, '//*[@id="pane-scene-tab"]/div/div[2]/div[2]/div[2]/div['
'1]/div/div')
for Object in fightObject:
monsterName = Object.find_element(By.XPATH, './div/div[2]/span')
href = Object.find_element(By.CSS_SELECTOR, 'div > div:nth-child(1) > div > svg ')
self.fightObject[monsterName.get_attribute('innerText')] = href
self.fightObject[MAP_MONSTER[self.map]].click()
print("挑战场景:", MAP_MONSTER[self.map])
def __setSkill(self, name):
skillList = self.driver.find_elements(By.XPATH, '//*[@id="app"]/div/div[4]/div/div/div/div[2]/div/div['
'2]/div/div[2]/div/div/div[1]/div[1]/div/div/div[1]/div/div')
for skill in skillList:
skillHref = skill.find_element(By.XPATH, './div/img')
skillName = skillHref.get_attribute("src").split('/')[-1].split('.')[0]
skillName = parse.unquote(skillName)
self.skills[skillName] = skillHref
# ActionChains(self.driver).send_keys(Keys.ARROW_UP).perform()
self.driver.execute_script("window.scrollBy(0,0)")
self.driver.execute_script("arguments[0].click();", self.skills[name])
time.sleep(.5)
auto = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div/div/div[2]/div/div[2]/div/div['
'2]/div/div/div[2]/div[2]/div/div[3]/div/div/div[2]')
self.driver.execute_script("arguments[0].click();", auto)
print("自动开启成功", end='、')
def __circulate(self):
button = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div/div/div[2]/div/div[2]/div/div['
'2]/div/div/div[1]/div[2]/div/div/div[2]/div')
self.driver.execute_script('arguments[0].click();', button)
print("循环挑战开启", end='、')
def __again(self):
self.againButton = self.driver.find_element(By.XPATH,
'//*[@id="app"]/div/div[4]/div/div/div/div[2]/div/div[2]/div/div['
'2]/div/div/div[1]/div[2]/button/span')
self.driver.execute_script("arguments[0].click();", self.againButton)
print("点击挑战成功")
def __save(self):
button = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div/div/div[3]/div/div['
'1]/div/div/div[2]/div[1]')
self.driver.execute_script("arguments[0].click();", button)
print("省流模式开启")
def __changeSpan(self):
"""
切换累计页面,用于获取胜利次数,以及点击再次挑战按钮
:return:
"""
cumulative = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div/div/div[3]/div/div['
'2]/div/div[1]/div/div/div/div[1]/div[2]/div/span')
self.driver.execute_script("arguments[0].click();", cumulative)
print("累计获胜切换成功", end='、')
def __getVictor(self):
"""
获取胜利次数,用于显示和点击
:return:
"""
self.victorCount = self.driver.find_element(By.XPATH,
'//*[@id="app"]/div/div[4]/div/div/div/div[3]/div/div[2]/div/div['
'2]/div/div/div/div[2]/div[1]/span')
print("获取战斗次数成功")
def __getMessage(self):
self.messageSpan = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div/div/div[3]/div/div['
'2]/div/div[2]/div/div/p[1]/span/span/span')
def __getBloodAndMagic(self):
"""
获取气血值和魔法值,当气血值或者魔法值低于200时,退出程序
:return:
"""
blood = self.driver.find_element(By.XPATH,
'//*[@id="app"]/div/div[4]/div/div/div/div[1]/div/div[2]/div/div[2]/div['
'1]/div/div[1]/div[23]').get_attribute("innerText")
magic = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div/div/div[1]/div/div[2]/div/div['
'2]/div[1]/div/div[1]/div[25]').get_attribute('innerText')
if eval(blood.split(":")[-1].replace("w", '')) < 200 or eval(magic.split(":")[-1].replace("w", '')) < 200:
exit()
def __setting(self):
"""
将页尾设置为Display为None,即不显示,选择聊天框为队伍聊天,并发送test测试
:return:
"""
footer_el = self.driver.find_element(By.XPATH,
'//*[@id="app"]/div/footer/div')
self.driver.execute_script("arguments[0].style=arguments[1]", footer_el, 'display: none')
choice = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div/div/div[3]/div/div[3]/div/div['
'2]/div/div[1]/div/div[1]')
choice.click()
choiceList = self.driver.find_elements(By.XPATH, "//div[@class='n-base-select-option__content']")
choiceDict = {"地图": choiceList[0], "队伍": choiceList[1], "宗门": choiceList[2], "世界": choiceList[3]}
choiceDict['队伍'].click()
inputText = self.driver.find_element(By.XPATH, '//input[@class="n-input__input-el" and @placeholder="请输入"]')
inputText.send_keys("text")
sendButton = self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[4]/div/div/div/div[3]/div/div['
'3]/div/div[2]/div/button')
sendButton.click()
def __getChat(self):
"""
获取聊天框中的第一条信息
:return:
"""
charDiv = self.driver.find_element(By.XPATH, '//div[@class="chat-log"]').get_attribute("innerText")
if charDiv != '':
print(charDiv.split("\n")[0])
def __getTeamMember(self):
memberList = self.driver.find_elements(By.XPATH, '//div[@class="el-row team-list"]/div')
print("当前队伍人数:" + str(len(memberList) - 2))
for member in memberList[2:]:
print(member.find_element(By.XPATH, 'div/div/div[1]/span').get_attribute("innerText") + "战力:" +
member.find_element(By.XPATH, 'div/div/div[2]').get_attribute("innerText"))
def __getExperiencePerMin(self):
self.experiencePerMin = self.driver.find_element(By.XPATH,
'//*[@id="app"]/div/div[4]/div/div/div/div[3]/div/div['
'2]/div/div[2]/div/div/div/div[2]/div[4]/span')
print("获取每分钟经验成功")
def __getSpoils(self):
self.spoils = self.driver.find_elements(By.XPATH,
'//span[@class="bat-log-p goods"]')
for spoils in self.spoils:
print(spoils.get_attribute("innerText").replace('\n', ''), end=' ')
print()
def run(self, username):
self.__login(USER[username])
self.__setMap()
self.__setOption()
self.__flush()
self.__createTeam(number='4')
self.__setFightObject()
self.__circulate()
if username == "大号":
self.__setSkill("落叶萧萧")
print("当前技能:落叶萧萧", end='、')
else:
self.__setSkill("破空闪耀")
print("当前技能:破空闪耀", end='、')
self.__changeSpan()
self.__getVictor()
self.__save()
self.__setting()
self.__getExperiencePerMin()
while True:
"""
每过1分钟打印一次获胜次数
"""
message = self.victorCount.get_attribute("innerText")
time.sleep(10)
self.__getTeamMember()
print(message, time.strftime("%Y:%m:%d %H:%M:%S"))
print(self.experiencePerMin.get_attribute("innerText"))
self.__getSpoils()
print("----------------------")
print("聊天: ", end='')
self.__getChat()
print("----------------------")
if __name__ == "__main__":
process = Niming()
print("程序开始运行:", time.strftime("%Y:%m:%d %H:%M:%S"))
try:
process.run("大号")
except Exception as e:
print(e)
process.run("大号")
服务器程序不挂断
- 对于服务器上的程序在服务器连接断开时,希望其在后台继续运行,就要将其固定到一个端口上 执行
nohup python3 -u ./nimingxx_0.1.py > log.out 2>&1 &
- 可以使用supervisor
- 安装supervisor
apt-get install supervisor
- 配置要进行的command
vim /etc/supervisor/supervisord.conf
在文件的后面加上
[program:Junziyuechuan]
command=python3 /home/nimingxx/nimingxx_0.1.py
autostart=true
autorestart=true
stdout_logfile=/home/nimingxx/out.log
stderr_logfile=/home/nimingxx/err.log
program:自己程序取的名称 command: 就是要开始执行的命令 autostrat:服务器启动是否自动启动 autostrat:服务器重启是否自动重启 stdout_logfile:正常日志输出
- 启动服务 执行
supervisord
这错误,是在第一次运行时要指定conf文件,就是上面编辑的那个文件
supervisord -c /etc/supervisor/supervisord.conf
这个错误就是已经开启了一个端口用来跑supervisor,需要将其kill
查询端口号
ps -aux|grep supervisord
kill 端口即可
kill -9 端口号
出现这个
出现这个错误,就是自己的supervisord.conf配置出错了
我就出现了错误
原因是,我的python环境是配置的虚拟环境,而上面的command我配置的是全局的python解释器,这样就会报找不到包的错误,所以我就要更改command
command=/home/nimingxx/selenium3.8/bin/python3 /home/nimingxx/nimingxx_0.1.py
然后shutdown,重启就正常了
这里有一些常用的supervisor指令
service supervisor stop #停止supervisor服务
service supervisor start #启动supervisor服务
supervisorctl shutdown #关闭所有任务
supervisorctl stop|start program_name #启动或停止服务
supervisorctl status #查看所有任务状态
很大可能会报错
出现Unlinking stale socket /var/run/supervisor.sock 只需要执行
出现Unlinking stale socket /var/run/supervisor/supervisor.sock
则执行
unlink /var/run/supervisor/supervisor.sock
create 2022/5/1add 2022/5/3