用python实现自动玩Npubits的21点游戏

用python实现自动玩Npubits的21点游戏

21点的主页面

https://---

(此处不提供链接,用户直接在网站首页点击21点后,地址栏的链接便是。)

需要知道的关键点

写代码时用来抓取数据的关键点

1. 等待开局

若之前的21点还没有结束(暂时没有对手上线),那么不能开局,需等待之前的结束。若需等待,主页面包含以下内容

<button type="submit" class="btn btn-default">刷新</button>
2. 可以开始

若可以开始游戏,主页面包含以下内容

<button type="submit" class="btn btn-primary">开始游戏!</button>
3. 开始21点

向主页面post数据

game: hit,
start: yes
4. 判断点数

判断每次操作后,主页面返回的网页内容。点数的html样式如下:

<b>点数 = 16</b>
5. 继续摸牌

向主页面post数据

game: hit
6. 停止摸牌

向主页面post数据

game: stop

Python脚本思路

  1. 等待开局。
  2. 开始21点。
  3. 判断点数。
  4. 若点数大于20,回到第1步。
  5. 若点数大于17,则去到第8步。(17可变,只是我认为17点够大了)
  6. 若点数小于等于17,则去到第7步。
  7. 继续摸牌,回到第3步。
  8. 停止摸牌,回到第1步。

toulanboy - http://www.cnblogs.com/toulanboy/

代码实现

1. 关键逻辑:开始-摸牌-停止
#(**此处不提供链接,用户直接在网站首页点击21点后,地址栏的链接便是。**)
url = ‘https://----‘ 

#不停地玩21点
while True:
    #先看之前的是否结束了
    result = getData(url)
    time.sleep(5) # toulanboy - http://www.cnblogs.com/toulanboy/
    if result == 0: #如果还没结束,则继续刷新
        print "之前的尚没结束,等待中"
    elif result == 1:#如果结束了,则开始游戏
        point = postData(url, startValues)#发出“开始游戏”请求
        print "已开局,当前点数 = %d" % point
        #大于20点,系统会自动结束,故在这里我只需在小于21点的情况下摸牌
        while point <= 20:
            if point >= 17:#我认为只要大于17点我满足了,所以大于17点就停止摸牌
                time.sleep(1)
                postData(url, stopValues)#发出“停止摸牌”请求
                print "停止摸牌了,当前点数 = %d" % point
                break
            else:#小于17点则继续摸牌
                time.sleep(1)
                point = postData(url, hitValues)#发出“继续摸牌”请求
                print "又摸牌了,当前点数 = %d" % point

        print "这局结束了,当前点数 = %d" % point
    else:#出现异常,则停止游戏。等待渣渣看日志看看哪里出问题了。
        sendEmail("[email protected]", "Some errors occurred in python script for npubits", "Some errors occurred in python script for npubits")
        break
2. 用get请求判断是否可以开始游戏
#function - Get网页
#若网页显示之前的没结束,则返回0
#若网页显示可以开始新的一局,则返回1
#其它情况返回-1
def getData(url):
    headers = {
        ‘User-Agent‘ : ‘-‘,#建议设置
        ‘cookie‘:‘-‘#我没做登陆,所以手动弄cookie
        }
    try:
        response = requests.get(url, headers=headers)
        indexHtmlCode = response.text
        indexHtmlCode =  indexHtmlCode.encode(‘utf-8‘)

        #判断是否有刷新按钮,若有,说明上局没结束
        freshRegex = r‘刷新</button>‘
        result = re.findall(freshRegex, indexHtmlCode)
        if result:
            return 0
# toulanboy - http://www.cnblogs.com/toulanboy/
        #判断是否有开始游戏按钮,若有,说明可以开始游戏
        beginRegex = r‘开始游戏!</button>‘
        result = re.findall(beginRegex, indexHtmlCode)
        if result:
            return 1

        return -1

    except Exception as e:
        return -1
3. 用Post请求实现开始/摸牌/停止的动作

toulanboy - http://www.cnblogs.com/toulanboy/

### 不同动作需要的数据不一样
# 开始游戏
startValues = {
    "game":"hit",
    "start":"yes"
}
# 继续摸牌
hitValues = {
    "game":"hit"
}
# 停止摸牌
stopValues = {
    "game":"stop"
}

#function - Post网页
#若是开始和摸牌,则返回点数
#页面没有点数(停止摸牌操作会出现),则返回0
#异常,返回-1
def postData(url, values):
    dd = urllib.urlencode(values)
    headers = {
            "Content-Length":str(len(dd)),
            "Content-Type":"application/x-www-form-urlencoded",
            ‘Cache-Control‘:‘max-age=0‘,#上述三个参数其实应该不用手动添加,有可能request库会帮我们添加。有待验证。
            ‘User-Agent‘ : ‘-‘,#自己补充
            ‘cookie‘:‘-‘#自己补充
            }
    try:
        response = requests.post(url, data=dd,headers=headers)
        indexHtmlCode = response.text
        indexHtmlCode =  indexHtmlCode.encode(‘utf-8‘)
# toulanboy - http://www.cnblogs.com/toulanboy/
        # 查看返回的网页的点数
        pointRegex = r‘点数\s?=\s?(\d*)<‘
        result = re.findall(pointRegex, indexHtmlCode)
        if result:
            return int(result[0])
        else:
            return 0

    except Exception as e:
        return -1

完整代码

为了便于维护,完整代码中增加了日志记录和邮件提醒

#!/usr/bin/python
# coding=utf-8
# 时间:2018-08-22
# 作者:toulanboy
# 缘由:想实现自动玩npubits的21点游戏

import requests
import re
import urllib
import time
import logging
import smtplib
from email.mime.text import MIMEText

#配置日志
logging.basicConfig(filename=‘my.log‘,format=‘[%(asctime)s-%(filename)s-%(levelname)s:%(message)s]‘, level = logging.INFO,filemode=‘a‘,datefmt=‘%Y-%m-%d %I:%M:%S %p‘)

### 不同动作需要的数据不一样
# 开始游戏
startValues = {
    "game":"hit",
    "start":"yes"
}
# 继续摸牌
hitValues = {
    "game":"hit"
}
# 停止摸牌
stopValues = {
    "game":"stop"
}
# toulanboy - http://www.cnblogs.com/toulanboy/
#function - Post网页
#若是开始和摸牌,则返回点数
#页面没有点数(停止摸牌操作会出现),则返回0
#异常,返回-1
def postData(url, values):
    dd = urllib.urlencode(values)
    headers = {
            "Content-Length":str(len(dd)),
            "Content-Type":"application/x-www-form-urlencoded",
            ‘Cache-Control‘:‘max-age=0‘,#上述三个参数其实应该不用手动添加,有可能request库会帮我们添加。有待验证。
            ‘User-Agent‘ : ‘-‘,#自己补充
            ‘cookie‘:‘-‘#自己补充
            }
    try:
        response = requests.post(url, data=dd,headers=headers)
        indexHtmlCode = response.text
        indexHtmlCode =  indexHtmlCode.encode(‘utf-8‘)
        # 提取网页主干,存入日志(方便后期的分析)
        body = re.findall(r‘<div\s?id=\‘main\‘\s?class=\‘well\s?no-border-radius\‘>.*?</div>‘,indexHtmlCode, re.S)
        if body:
            logging.info(body[0])
        else:
            logging.info(indexHtmlCode)
        # 查看返回的网页的点数
        pointRegex = r‘点数\s?=\s?(\d*)<‘
        result = re.findall(pointRegex, indexHtmlCode)
        if result:
            return int(result[0])
        else:
            return 0

    except Exception as e:
        logging.error(e)
        return -1

#function - Get网页
#若网页显示之前的没结束,则返回0
#若网页显示可以开始新的一局,则返回1
#其它情况返回-1
def getData(url):
    headers = {
        ‘User-Agent‘ : ‘-‘,#建议设置
        ‘cookie‘:‘-‘#我没做登陆,所以手动弄cookie
        }
    try:
        response = requests.get(url, headers=headers)
        indexHtmlCode = response.text
        indexHtmlCode =  indexHtmlCode.encode(‘utf-8‘)

        #判断是否有刷新按钮,若有,说明上局没结束
        freshRegex = r‘刷新</button>‘
        result = re.findall(freshRegex, indexHtmlCode)
        if result:
            return 0

        #判断是否有开始游戏按钮,若有,说明可以开始游戏
        beginRegex = r‘开始游戏!</button>‘
        result = re.findall(beginRegex, indexHtmlCode)
        if result:
            return 1

        # 若以上情况都不是,有可能是cookie过期了
        loginRegex = r‘您尚未登录</body>‘
        result = re.findall(loginRegex, indexHtmlCode)
        if result:
            return 2

        # 如果不是cookie过期,则需打印当前错误信息(记录返回的网页源代码),方便后面找错
        logging.error(indexHtmlCode)

    except Exception as e:
        logging.error(e)
        return -1

#发邮件 (收件人 ,邮件主题 ,邮件正文)
def sendEmail(_to, subject, mainText):
    _user = "-"  #登录的163邮箱
    _pwd = "-"   #163邮箱授权码
    msg = MIMEText(mainText)    #邮件正文
    msg["Subject"] = subject    #邮件主题
    msg["From"]    = _user      #发件人
    msg["To"]      = _to        #收件人

    try:
        s = smtplib.SMTP_SSL("smtp.163.com", 465)
        s.login(_user, _pwd)#登录
        s.sendmail(_user, _to, msg.as_string())#发送
        s.quit()#退出登录
        logging.info("邮件发送成功!")
        print "邮件发送成功!"
    except smtplib.SMTPException,e:
        logging.info("邮件发送失败,%s"%e[0])
        print "邮件发送失败,%s"%e[0]

#(**此处不提供链接,用户直接在网站首页点击21点后,地址栏的链接便是。**)
url = ‘https://----‘ 

#不停地玩21点
while True:
    #先看之前的是否结束了
    result = getData(url)
    time.sleep(5)
    if result == 0: #如果还没结束,则继续刷新
        print "之前的尚没结束,等待中"
    elif result == 1:#如果结束了,则开始游戏
        point = postData(url, startValues)#发出“开始游戏”请求
        logging.info("已开局,当前点数 = %d" % point)
        print "已开局,当前点数 = %d" % point
        #大于20点,系统会自动结束,故在这里我只需在小于21点的情况下摸牌
        while point <= 20:
            if point >= 17:#我认为只要大于17点我满足了,所以大于17点就停止摸牌
                time.sleep(1)
                postData(url, stopValues)#发出“停止摸牌”请求
                logging.info("停止摸牌了,当前点数 = %d" % point)
                print "停止摸牌了,当前点数 = %d" % point
                break
            else:#小于17点则继续摸牌
                time.sleep(1)
                point = postData(url, hitValues)#发出“继续摸牌”请求
                logging.info("又摸牌了,当前点数 = %d" % point)
                print "又摸牌了,当前点数 = %d" % point

        logging.info("这局结束了,当前点数 = %d" % point)
        print "这局结束了,当前点数 = %d" % point
    else:#出现异常,则停止游戏。等待渣渣看日志看看哪里出问题了。
        sendEmail("[email protected]", "Some errors occurred in python script for npubits", "Some errors occurred in python script for npubits")
        break

toulanboy - http://www.cnblogs.com/toulanboy/

完毕。python刚刚学到点皮毛,代码习惯可能不好,希望大佬多多包涵。

如若有大佬愿意指点,非常感谢。

原文地址:https://www.cnblogs.com/toulanboy/p/9522848.html

时间: 2024-10-29 03:13:37

用python实现自动玩Npubits的21点游戏的相关文章

不敢想!不敢想!我用Python自动玩转2048游戏

近来在折腾selenium自动化, 感觉配合爬虫很有意思, 大多数以前难以模拟登录的网站都可以爬了,折腾了这么久, 于是想自动玩个2048游戏!嘿嘿, 我是一个不擅长玩游戏的人, 以前玩2048就经常得了很低的分,每每想起都"痛心疾首", 所以我打算拿2048开刀, 通过几种方式, 让程序帮我玩! 环境: python 3.5 用到的库: re, random, time, selenium 2048网页版: http://2048.oubk.com 本篇用到了selenium,运行前

教你从头到尾利用DQN自动玩flappy bird(全程命令提示,纯小白教程)

教你从头到尾利用DQN自动玩flappy bird(全程命令提示.纯小白教程) 作者:骁哲.李伟.July说明:本教程主要由骁哲编写,且最后跑的是yenchenlin的github开源demo.如遇问题欢迎加Q群交流:472899334.时间:二零一六年十月十三日. 前言 我们在上一篇教程<基于torch学汪峰写歌词.聊天机器人.图像着色/生成.看图说话.字幕生成>中说到:"让每一个人都能玩一把,无限降低初学朋友的实验门槛",那是否能把难度再次降低呢,比如部分同学不熟悉Li

python IDLE 自动提示功能

\Python27\Lib\idlelib\目录下 config-extensions.def文件修改等待时间 [AutoComplete] enable=1 popupwait=2000(2000表示2秒,修改为0) AutoComplete.py文件修改提示模块 import os import sys import string 在后面加载待提示的模块(import方式) 如: import urllib import urllib2 import re import cookielib

Python Scrapy 自动爬虫注意细节

一.首次爬取模拟浏览器 在爬虫文件中,添加start_request函数.如: def start_requests(self): ua = {"User-Agent": 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.2050.400 QQBrowser/9.5.10169.400'} yie

python vim自动补全

1.下载插件包 https://github.com/vim-scripts/Pydiction ##################### 包括三个文件 python_pydiction.vim #vim插件 complete-dict #python关键字和模块列表, pydiction.py  #python脚本,可以添加更多的模块 2.配置 #1.查看家目录下是否有.vim目录,若没有则创建. mkdir  -p  ~/.vim/after/ftplugin/pydiction #2.把

python基础教程_学习笔记21:文件和素材

文件和素材 打开文件 open函数用来打开文件,语法如下: open([name[,mode[,buffering]]) open函数使用一个文件名作为唯一的强制参数,然后返回一个文件对象.模式(mode)和缓冲(buffering)参数都是可选的. >>> f=open(r'D:\software(x86)\Python27\README.txt') 如果文件不存在,则出现错误: >>> f=open(r'D:\software(x86)\Python27\READM

【python】自动登录51cto家园

自动登录:http://home.51cto.com 1.分析: 使用httpfox抓取手动登录home.51cto.com的过程,过程如下: 点登录,提交用户名与密码到http://home.51cto.com/index.php?s=/Index/doLogin 这个地址,正确后,他会返回的内容包含很多链接,如第二个图片.然后分别get这些链接.请求完这些链接后,再访问个人主页http://home.51cto.com/index.php?s=/Home/index post成功后服务器返回

windows下python的自动截图功能

python的自动截取特别简单(注:python的版本为2.7...) 首先安装 PIL模块,这个模块去这里(http://www.pythonware.com/products/pil/)找到你版本对应的PIL安装包, 注意你的windows是多少位的系统,这个有区别比较重要 ok,进入代码部分: # -*- coding: cp936 -*-  #如果有中文则需要增加这个说明(我的版本里如果不加这句话,每次运行都会提示自动插入这行代码) from PIL import ImageGrab  

Python + Selenium 自动发布文章(一):开源中国

https://blog.csdn.net/qq_28804275/article/details/80891949 https://blog.csdn.net/qq_28804275/article/details/80891949Python + Selenium 自动发布文章系列:Python + Selenium 自动发布文章(一):开源中国Python + Selenium 自动发布文章(二):简书Python + Selenium 自动发布文章(三):CSDNPython + Sel