用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脚本思路
- 等待开局。
- 开始21点。
- 判断点数。
- 若点数大于20,回到第1步。
- 若点数大于17,则去到第8步。(17可变,只是我认为17点够大了)
- 若点数小于等于17,则去到第7步。
- 继续摸牌,回到第3步。
- 停止摸牌,回到第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