namedlxd 发表于 2019-9-11 01:05

投票活动规则分析与实现模拟投票

刷票行为不可取, 本文只做技术交流. 一切违规行为与作者无关!!!
刷票行为不可取, 本文只做技术交流. 一切违规行为与作者无关!!!
刷票行为不可取, 本文只做技术交流. 一切违规行为与作者无关!!!

今天在班级群里面看到, 有同学在拉票. 于是随手点进去帮忙投了一票.这个投票活动大概长这样, 打码是为了防止暴露投票活动信息.

当我们点击"点击投票"按钮的时候, 会弹出输入验证码的模态框, 输入验证码点击投票后显示投票成功.


1. 经历过投票的流程后, 不难发现, 整个过程中只有输入验证码的一个复杂过程. 于是就想模拟请求达到投票的效果.于是开始了下面的分析:1.投票没有记录是谁投的, 那么这里的已投票按钮肯定只在前端做了限制, 有过web开发经验的程序员很容易会想到cookie, 这里也正是用cookie存储投票记录限制前端. 通过清除cookie或换其他的浏览器, 发现还可以投票. 这里我用了chrome浏览器的无痕模式, 验证了这一点.


2. 由1可知, 既然是用cookie限制, 那么能不能清除cookie然后再投票呢? 这里我试了一下, 发现再次投票后, 前端页面的票数会加1, 刷新之后票数会复原, 由此可推测, 除了前端限制, 服务端也会去重. 这时在页面底端看到这样的提示信息: 同一设备每天对一家只能投一次. 猜想是根据ip来去重的, 于是我换了个ip, 再投票发现票数增加了, 刷新也没有减少, 由此可推断是根据ip去重的. 理论上分析到这里已经可以实现模拟投票了.


经过前面的分析, 总结出来一下几点难点:
[*] 验证码请求, 投票请求获取?
[*] 验证码如何自动填写?
[*] ip如何自动切换?



对于第一点, 我们可以在浏览器的控制台中抓取url并分析参数, 这一步较为简单, 在此略过.对于第二点, 有两种方案:
[*]方案一: 抓取图片, 通过神经网络识别验证码内容.
[*]方案二: 购买验证码识别的服务调用.

显然方案一成本太高, 这里采用了方案二.对于第三点, 可以通过代{过}{滤}理实现, 购买代{过}{滤}理服务.经过以上分析, 只需按部就班的写模拟程序实现:最开始我以为知识简单的在前端加了限制, 没有过滤ip, 所以就直接识别验证码, 然后发请求投票. 主要代码有以下部分:


import requests
import base64
import json

# 请求头, 投票链接和验证码链接不加请求头会返回404
headers = {
    'User-Agent':
    'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}

proxies = {}

# 获取要识别的图片验证码
response = requests.get('',
                        headers=headers, proxies=proxies)
# 识别验证码api需要通过base64编码提交
base64_data = base64.b64encode(response.content)

# 图片验证码识别url
predict_url = ''
# 根据验证码识别api, 组装数据提交识别验证码
code_resp = requests.post(predict_url, {
    'user': '',
    'pass': '',
    'file_base64': base64_data
})
# 解析返回数据, 获取识别结果
result = code_resp.content.decode(encoding='raw_unicode_escape')
result_json = json.loads(result, encoding='utf-8')
predict_result = result_json['pic_str']

# 投票url
vote_url = ''
# 发送请求 模拟投票
vote_resp = requests.get(vote_url.format(predict_result), headers=headers, proxies=proxies)
print(vote_resp.content.decode(encoding='utf-8'))

写完这个代码后, 兴奋的跑了一次, 发现虽然返回投票成功, 但是票数并没有增加, 这时我才想到前面分析的第二点, 根据ip去重, 于是去找了代{过}{滤}理池服务, 每次请求通过不同的代{过}{滤}理来模拟. 下面是获取代{过}{滤}理ip的一段代码.


# 获取代{过}{滤}理服务器ip
proxy_url = ''
proxy_resp = requests.get(proxy_url)
# 解析代{过}{滤}理ip
proxy_json = json.loads(proxy_resp.content, encoding='utf-8')
ip = proxy_json['data']['IP']
proxies = {
"http": "http://{}".format(ip),
"https": "http://{}".format(ip),
}


在使用代{过}{滤}理ip后, 我先尝试了 不用代{过}{滤}理获取验证码图片,然后使用代{过}{滤}理投票, 发现这样提示验证码错误. 于是推断出, 验证码是根据ip来分组的, 同一个ip只能提交同一个ip获取的验证码. 于是在获取验证码的时候也通过代{过}{滤}理服务器即可, 实现模拟投票.
本文就分析到这里.
如果有什么疑问, 欢迎大家留言, 我看到后会第一时间回复.
如果对大家有帮助, 麻烦动动小手, 给个评分.

hanshi 发表于 2019-9-11 07:43

可以直接使用吗?没看到投票网站的网址啊?

sdaza 发表于 2019-9-11 08:10

收藏看看

a920266279 发表于 2019-9-11 09:12

微信投票应该不行吧

namedlxd 发表于 2019-9-11 10:07

hanshi 发表于 2019-9-11 07:43
可以直接使用吗?没看到投票网站的网址啊?

只做技术上的交流, 具体案例要具体分析

namedlxd 发表于 2019-9-11 10:08

a920266279 发表于 2019-9-11 09:12
微信投票应该不行吧

理论上 有足够多的wx号 可以模拟
页: [1]
查看完整版本: 投票活动规则分析与实现模拟投票