文章目录

  • 安装必要环境
  • linux环境配置
  • 基本的使用
  • 创建浏览器控制
  • 访问网页
  • 获取元素
  • By
  • 等待浏览器相应
  • 元素交互
  • 网页游戏的挂载
  • 服务器程序不挂断

安装必要环境

  1. 安装selenium
pip install selenium
  1. 安装浏览器 这里我使用自带的Edge浏览器
  2. 安装浏览器driver 根据自己浏览器的版本,去下载Edgedriver,只需要前面的大版本一致就可以,但是还是尽量满足所有的版本一致比较好EdgeDriver所有版本
  3. 环境变量配置 可以将下载的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的方式

python selenium无痕模式 python selenium edge_开发语言

例如

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("大号")

服务器程序不挂断

  1. 对于服务器上的程序在服务器连接断开时,希望其在后台继续运行,就要将其固定到一个端口上 执行
nohup python3 -u ./nimingxx_0.1.py > log.out 2>&1 &
  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

python selenium无痕模式 python selenium edge_chrome_02

这错误,是在第一次运行时要指定conf文件,就是上面编辑的那个文件

supervisord -c /etc/supervisor/supervisord.conf

python selenium无痕模式 python selenium edge_selenium_03

这个错误就是已经开启了一个端口用来跑supervisor,需要将其kill

查询端口号

ps -aux|grep supervisord

kill 端口即可

kill -9 端口号

出现这个

python selenium无痕模式 python selenium edge_chrome_04

出现这个错误,就是自己的supervisord.conf配置出错了

我就出现了错误

原因是,我的python环境是配置的虚拟环境,而上面的command我配置的是全局的python解释器,这样就会报找不到包的错误,所以我就要更改command

command=/home/nimingxx/selenium3.8/bin/python3 /home/nimingxx/nimingxx_0.1.py

然后shutdown,重启就正常了

python selenium无痕模式 python selenium edge_chrome_05

这里有一些常用的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 只需要执行

python selenium无痕模式 python selenium edge_selenium_06

出现Unlinking stale socket /var/run/supervisor/supervisor.sock

则执行

unlink /var/run/supervisor/supervisor.sock

create 2022/5/1add 2022/5/3