一、前言

看了网上很多的教程都是通过OCR识别的,这种方法的优点在于通用性强。不同的答题活动都可以参加,但是缺点也明显,速度有限,并且如果通过调用第三方OCR,有次数限制。但是使用本教程提到的数据接口。我们能很容易的获取数据,速度快,但是接口是变化的,需要及时更新。

二、实战解析

1、背景介绍

百万英雄答题是一个最近很火爆的答题软件,答对12题的人,可以平分最后的奖金。奖金不错,笔者参加过几次,不过获得的都是小奖,最后几块钱的那种。对于不难的题目,能够直接百度出答案的题目,如果有个软件辅助实时给出参考,还是一件很舒服的事情。想干就干,走起!

2、先睹为快

先看下部署效果,通过服务器后端处理,通过前端显示,亲测延时3s:

转存失败重新上传取消

为啥做成这样呢?因为这样,别的人也可以通过浏览器进行访问,独乐不如众乐嘛!

Github开源地址:https://github.com/Jack-Cherish/python-spider

3、西瓜视频APP抓包

对于如何抓包,我想应该都会了,我在手机APP抓包教程中有详细讲解,如有不会的,请暂时移步:http://blog.csdn.net/c406495762/article/details/76850843

在比赛答题的时候,我们可以通过抓包,找到这样的接口(点击放大):

可以看到,参数如上图所示。其中heartbeat后面的参数是一个随着场次的增加,逐渐增加的一个数,后面其他的例如iid和device_id是每个人的用户信息,在接口的最后,有个rticket参数,这个是一个时间戳,可以通过time.time()模拟。

2018-1-17更新:据朋友反应,url的有效参数只有heartbeat和rticket参数,用户信息可以不填写。

注意:只有在答题直播开始的时候,才能通过接口抓取到数据,没有直播的时候,是获取不到数据的,是乱码。

通过这个接口获取数据,然后对数据进行解析,在通过百度知道索问题,简单高效。有了这个思想,就可以开始写代码了。

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

# -*-coding:utf-8 -*-

import requests

from lxml import etree

from bs4 import BeautifulSoup

import urllib

import time, re, types, os

"""

代码写的匆忙,本来想再重构下,完善好注释再发,但是比较忙,想想算了,所以自行完善吧!写法很不规范,勿见怪。

作者:  Jack Cui

Website:https://cuijiahua.com

注:     本软件仅用于学习交流,请勿用于任何商业用途!

"""

class BaiWan():

def __init__(self):

# 百度知道搜索接口

self.baidu = 'http://zhidao.baidu.com/search?'

# 百万英雄及接口,每个人的接口都不一样,里面包含的手机信息,因此不公布,请自行抓包,有疑问欢迎留言:https://cuijiahua.com/liuyan.html

self.api = 'https://api-spe-ttl.ixigua.com/xxxxxxx={}'.format(int(time.time()*1000))

# 获取答案并解析问题

def get_question(self):

to = True

while to:

list_dir = os.listdir('./')

if 'question.txt' not in list_dir:

fw = open('question.txt', 'w')

fw.write('百万英雄尚未出题请稍后!')

fw.close()

go = True

while go:

req = requests.get(self.api, verify=False)

req.encoding = 'utf-8'

html = req.text

print(html)

if '*' in html:

question_start = html.index('*')

try:

question_end = html.index('?')

except:

question_end = html.index('?')

question = html[question_start:question_end][2:]

if question != None:

fr = open('question.txt', 'r')

text = fr.readline()

fr.close()

if text != question:

print(question)

go = False

with open('question.txt', 'w') as f:

f.write(question)

else:

time.sleep(1)

else:

to = False

else:

to = False

temp = re.findall(r'[\u4e00-\u9fa5a-zA-Z0-9\+\-\*/]', html[question_end+1:])

b_index = []

print(temp)

for index, each in enumerate(temp):

if each == 'B':

b_index.append(index)

elif each == 'P' and (len(temp) - index) <= 3 :

b_index.append(index)

break

if len(b_index) == 4:

a = ''.join(temp[b_index[0] + 1:b_index[1]])

b = ''.join(temp[b_index[1] + 1:b_index[2]])

c = ''.join(temp[b_index[2] + 1:b_index[3]])

alternative_answers = [a,b,c]

if '下列' in question:

question = a + ' ' + b + ' ' + c + ' ' + question.replace('下列', '')

elif '以下' in question:

question = a + ' ' + b + ' ' + c + ' ' + question.replace('以下', '')

else:

alternative_answers = []

# 根据问题和备选答案搜索答案

self.search(question, alternative_answers)

time.sleep(1)

def search(self, question, alternative_answers):

print(question)

print(alternative_answers)

infos = {"word":question}

# 调用百度接口

url = self.baidu + 'lm=0&rn=10&pn=0&fr=search&ie=gbk&' + urllib.parse.urlencode(infos, encoding='GB2312')

print(url)

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36',

}

sess = requests.Session()

req = sess.get(url = url, headers=headers, verify=False)

req.encoding = 'gbk'

# print(req.text)

bf = BeautifulSoup(req.text, 'lxml')

answers = bf.find_all('dd',class_='dd answer')

for answer in answers:

print(answer.text)

# 推荐答案

recommend = ''

if alternative_answers != []:

best = []

print('\n')

for answer in answers:

# print(answer.text)

for each_answer in alternative_answers:

if each_answer in answer.text:

best.append(each_answer)

print(each_answer,end=' ')

# print(answer.text)

print('\n')

break

statistics = {}

for each in best:

if each not in statistics.keys():

statistics[each] = 1

else:

statistics[each] += 1

errors = ['没有', '不是', '不对', '不正确','错误','不包括','不包含','不在','错']

error_list = list(map(lambda x: x in question, errors))

print(error_list)

if sum(error_list) >= 1:

for each_answer in alternative_answers:

if each_answer not in statistics.items():

recommend = each_answer

print('推荐答案:', recommend)

break

elif statistics != {}:

recommend = sorted(statistics.items(), key=lambda e:e[1], reverse=True)[0][0]

print('推荐答案:', recommend)

# 写入文件

with open('file.txt', 'w') as f:

f.write('问题:' + question)

f.write('\n')

f.write('*' * 50)

f.write('\n')

if alternative_answers != []:

f.write('选项:')

for i in range(len(alternative_answers)):

f.write(alternative_answers[i])

f.write('  ')

f.write('\n')

f.write('*' * 50)

f.write('\n')

f.write('参考答案:\n')

for answer in answers:

f.write(answer.text)

f.write('\n')

f.write('*' * 50)

f.write('\n')

if recommend != '':

f.write('最终答案请自行斟酌!\t')

f.write('推荐答案:' + sorted(statistics.items(), key=lambda e:e[1], reverse=True)[0][0])

if __name__ == '__main__':

bw = BaiWan()

bw.get_question()

获取数据和查找答案就是这样,很简单,代码写的也较为凌乱,大牛可以按照这个思路改一改。

4、网站部署

没做过后端和前端,花了一天时间,现学现卖弄好的,javascript也是现看现用,百度的程序,调试调试而已。可能有很多用法比较low的地方,用法不对,请勿见怪,有大牛感兴趣,可以自行完善。

这是我当时看的一些文章:

Node.js和Socket.IO通信基础:菜鸟学习nodejs--Socket.IO即时通讯

Node.js逐行读取txt文件:Line-Reader

Node.js定时任务:Node-Schedule

后端app.js:

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

var http = require('http');

var fs = require('fs');

var schedule = require("node-schedule");

var message = {};

var count = 0;

var server = http.createServer(function (req,res){

fs.readFile('./index.html',function(error,data){

res.writeHead(200,{'Content-Type':'text/html'});

res.end(data,'utf-8');

});

}).listen(80);

console.log('Server running!');

var lineReader = require('line-reader');

function messageGet(){

lineReader.eachLine('file.txt', function(line, last) {

count++;

var name = 'line' + count;

console.log(name);

console.log(line);

message[name] = line;

});

if(count == 25){

count = 0;

}

else{

for(var i = count+1; i <= 25; i++){

var name = 'line' + i;

message[name] = 'f';

}

count = 0;

}

}

var io = require('socket.io').listen(server);

var rule = new schedule.RecurrenceRule();

var times = [];

for(var i=1; i<1800; i++){

times.push(i);

}

rule.second = times;

schedule.scheduleJob(rule, function(){

messageGet();

});

io.sockets.on('connection',function(socket){

// console.log('User connected' + count + 'user(s) present');

socket.emit('users',message);

socket.broadcast.emit('users',message);

socket.on('disconnect',function(){

console.log('User disconnected');

//socket.broadcast.emit('users',message);

});

});

前端index.html:

XHTML

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8" />

<meta http-equiv="refresh" content="2">

<title>Jack Cui答题辅助系统</title>

</head>

<body>

<h1>百万英雄答题辅助系统</h1>

<p id="line1"></p>

<p id="line2"></p>

<p id="line3"></p>

<p id="line4"></p>

<p id="line5"></p>

<p id="line6"></p>

<p id="line7"></p>

<p id="line8"></p>

<p id="line9"></p>

<p id="line10"></p>

<p id="line11"></p>

<p id="line12"></p>

<p id="line13"></p>

<p id="line14"></p>

<p id="line15"></p>

<p id="line16"></p>

<p id="line17"></p>

<p id="line18"></p>

<p id="line19"></p>

<p id="line20"></p>

<p id="line21"></p>

<p id="line22"></p>

<p id="line23"></p>

<p id="line24"></p>

<p id="line25"></p>

<script src="https://222.222.124.77:9001/jquery.min.js"></script>

<script src="/socket.io/socket.io.js"></script>

<script>

var socket = io.connect('http://你的IP:端口');

var line1 = document.getElementById('line1');

var line2 = document.getElementById('line2');

var line3 = document.getElementById('line3');

var line4 = document.getElementById('line4');

var line5 = document.getElementById('line5');

var line6 = document.getElementById('line6');

var line7 = document.getElementById('line7');

var line8 = document.getElementById('line8');

var line9 = document.getElementById('line9');

var line10 = document.getElementById('line10');

var line11 = document.getElementById('line11');

var line12 = document.getElementById('line12');

var line13 = document.getElementById('line13');

var line14 = document.getElementById('line14');

var line15 = document.getElementById('line15');

var line16 = document.getElementById('line16');

var line17 = document.getElementById('line17');

var line18 = document.getElementById('line18');

var line19 = document.getElementById('line19');

var line20 = document.getElementById('line20');

var line21 = document.getElementById('line21');

var line22 = document.getElementById('line22');

var line23 = document.getElementById('line23');

var line24 = document.getElementById('line24');

var line25 = document.getElementById('line25');

socket.on('users',function(data){

if(data.line1 == 'f'){

line1.innerHTML = ''

}

else{

line1.innerHTML = data.line1

}

if(data.line2 == 'f'){

line2.innerHTML = ''

}

else{

line2.innerHTML = data.line2

}

if(data.line3 == 'f'){

line3.innerHTML = ''

}

else{

line3.innerHTML = data.line3

}

if(data.line4 == 'f'){

line4.innerHTML = ''

}

else{

line4.innerHTML = data.line4

}

if(data.line5 == 'f'){

line5.innerHTML = ''

}

else{

line5.innerHTML = data.line5

}

if(data.line6 == 'f'){

line6.innerHTML = ''

}

else{

line6.innerHTML = data.line6

}

if(data.line7 == 'f'){

line7.innerHTML = ''

}

else{

line7.innerHTML = data.line7

}

if(data.line8 == 'f'){

line8.innerHTML = ''

}

else{

line8.innerHTML = data.line8

}

if(data.line9 == 'f'){

line9.innerHTML = ''

}

else{

line9.innerHTML = data.line9

}

if(data.line10 == 'f'){

line10.innerHTML = ''

}

else{

line10.innerHTML = data.line10

}

if(data.line11 == 'f'){

line11.innerHTML = ''

}

else{

line11.innerHTML = data.line11

}

if(data.line12 == 'f'){

line12.innerHTML = ''

}

else{

line12.innerHTML = data.line12

}

if(data.line13 == 'f'){

line13.innerHTML = ''

}

else{

line13.innerHTML = data.line13

}

if(data.line14 == 'f'){

line14.innerHTML = ''

}

else{

line14.innerHTML = data.line14

}

if(data.line15 == 'f'){

line15.innerHTML = ''

}

else{

line15.innerHTML = data.line15

}

if(data.line16 == 'f'){

line16.innerHTML = ''

}

else{

line16.innerHTML = data.line16

}

if(data.line17 == 'f'){

line17.innerHTML = ''

}

else{

line17.innerHTML = data.line17

}

if(data.line18 == 'f'){

line18.innerHTML = ''

}

else{

line18.innerHTML = data.line18

}

if(data.line19 == 'f'){

line19.innerHTML = ''

}

else{

line19.innerHTML = data.line19

}

if(data.line20 == 'f'){

line20.innerHTML = ''

}

else{

line20.innerHTML = data.line20

}

if(data.line21 == 'f'){

line21.innerHTML = ''

}

else{

line21.innerHTML = data.line21

}

if(data.line22 == 'f'){

line22.innerHTML = ''

}

else{

line22.innerHTML = data.line22

}

if(data.line23 == 'f'){

line23.innerHTML = ''

}

else{

line23.innerHTML = data.line23

}

if(data.line24 == 'f'){

line24.innerHTML = ''

}

else{

line24.innerHTML = data.line24

}

if(data.line25 == 'f'){

line25.innerHTML = ''

}

else{

line25.innerHTML = data.line25

}

});

</script>

</body>

</html>

将这些部署到服务器上。这是我的部署效果:

部署好后。使用指令运行Node.js服务:

Shell

1

node app.js

运行python3脚本:

Shell

1

python3 baiwan.py

如果一切都搭建好了,那么这个百万英雄答题辅助系统就可以运行了!

三、总结

  • 本软件仅用于学习交流,请勿用于任何商业用途。
  • 也可以对代码进行简单修改,python打印信息,只在本地查看,无需写入txt文件,部署到服务器上。
  • 代码乱,没有经过优化,还需重构。

python爬虫进阶教程:百万英雄答题辅助系统相关推荐

  1. python 123 io网站答题如果最小化会有提示吗_爬虫进阶教程:百万英雄答题辅助系统...

    百万英雄答题辅助系统 var socket = io.connect('http://你的IP:端口'); var line1 = document.getElementById('line1'); ...

  2. 爬虫进阶教程:极验(GEETEST)验证码破解教程

    原文链接及原作者:爬虫进阶教程:极验(GEETEST)验证码破解教程 | Jack Cui 一.前言 爬虫最大的敌人之一是什么?没错,验证码![Geetest]作为提供验证码服务的行家,市场占有率还是 ...

  3. python爬虫菜鸟教程-Python 应该怎么学?

    不多BB,直接上干货! 现在很多学校都已经将Python作为入门的编程语言了,在目前特别火的机器学习.人工智能领域,Python可以说是标配的编程语言. 所以我由浅入深的整理了一些Python的资源和 ...

  4. Python爬虫进阶——urllib模块使用案例【淘宝】

    Python爬虫基础--HTML.CSS.JavaScript.JQuery网页前端技术 Python爬虫基础--正则表达式 Python爬虫基础--re模块的提取.匹配和替换 Python爬虫基础- ...

  5. python爬虫项目实战教学视频_('[Python爬虫]---Python爬虫进阶项目实战视频',)

    爬虫]---Python 爬虫进阶项目实战 1- Python3+Pip环境配置 2- MongoDB环境配置 3- Redis环境配置 4- 4-MySQL的安装 5- 5-Python多版本共存配 ...

  6. python爬虫入门教程--优雅的HTTP库requests(二)

    requests 实现了 HTTP 协议中绝大部分功能,它提供的功能包括 Keep-Alive.连接池.Cookie持久化.内容自动解压.HTTP代理.SSL认证等很多特性,下面这篇文章主要给大家介绍 ...

  7. python爬取图片教程-推荐|Python 爬虫系列教程一爬取批量百度图片

    Python 爬虫系列教程一爬取批量百度图片https://blog.csdn.net/qq_40774175/article/details/81273198# -*- coding: utf-8 ...

  8. python基础代码库-python爬虫基础教程:requests库(二)代码实例

    get请求 简单使用 import requests ''' 想要学习Python?Python学习交流群:973783996满足你的需求,资料都已经上传群文件,可以自行下载! ''' respons ...

  9. Python爬虫进阶五之多线程的用法

    前言 我们之前写的爬虫都是单个线程的?这怎么够?一旦一个地方卡到不动了,那不就永远等待下去了?为此我们可以使用多线程或者多进程来处理. 首先声明一点! 多线程和多进程是不一样的!一个是 thread ...

最新文章

  1. 从数据集到2D和3D方法,一文概览目标检测领域进展
  2. Linux之软连接和硬链接
  3. 按照标题排序mysql_Oracle EBS Form中实现点击列标题进行排序
  4. 第五章:序列(列表,元组,字典,集合,字典,字符串)
  5. 中国吉他效果市场趋势报告、技术动态创新及市场预测
  6. 一个通配符引起的错误
  7. Android7.0无需FileProvide搞定URI拍照、应用安装问题
  8. Tomcat 日志概述
  9. Sqlserver过滤数据
  10. TFN系列超声波探伤仪为什么在众多品牌竞争中脱颖而出
  11. 习题6.14 编一个程序,将两个字符串s1和s2比较,若s1 > s2,输出一个正数;若s1 = s2, 输出0;若s1 < s2,输出一个负数。不要用strcmp函数。两个字符串用gets函数输入。
  12. u3d学习:helloworld
  13. linux命令之head、tail命令具体解释
  14. 系统资源的观察(摘自鸟哥的私房菜)
  15. 浏览器源代码下载图片原图,手把手教学
  16. Linux管理员权限的相关命令
  17. 矩阵相关操作和矩阵快速幂
  18. Linux系统挂起之后退出的方法
  19. RAID数据恢复技术介绍
  20. 倩女幽魂手游服务器维护多久,倩女幽魂手游11月22日在线维护公告

热门文章

  1. “智囊”机器人:让我为你解答工作中的任何问题!
  2. Unabe to login, status: 526
  3. iOS 11 下 UICollectionView 出现滚动条被 HeaderView 遮挡的问题
  4. codevs1521 华丽的吊灯
  5. PHP安装imagemagick扩展imagick
  6. ASP.NET 5 - $.ajax post JSON.stringify(para) is null
  7. mouseleave mouseout时候悬浮框不应该消失的时候消失了 css 解决办法
  8. String.Empty,NULL和的区别
  9. 远离ARP*** ARP防火墙新版发布
  10. DockOne技术分享:十个问题带你了解Windows Docker