五一在即:有哪些办法能阻止票贩子和我们一起抢票?
背景
五一就要来了,本来准备去淄博吃烧烤,结果发现根本抢不到机票。了解了一下原因,原来是黄牛的恶意爬虫把票都抢完了,现在买票,只能通过黄牛的渠道,多花几倍的钱来买了。
有鉴于此,想试试能不能针对这种爬虫防止相关问题,当然是站在航空公司的角度,就个人而言,躺平任嘲就得了。
恶意爬虫的相关特征
对于恶意爬虫的特征,航空公司自己有总结:
1、访问的目标网页比较集中:“爬虫”代理人目标明确,主要是爬取班次、价格、数量等核心信息,因此只浏览访问几个固定页面,不访问其他页面。
**2、查询订票等行为很有规律:**由于“爬虫”是程序化操作,按照预先设定的流程进行访问等,因此呈现出毫无思维、但很有规律、有节奏且持续的行为。
3、同一设备上有规模化的访问和操作:“爬虫”的目的是最短时间内抓取最多信息,因此同一设备会有大量离散的行为,包括访问、浏览、查询等。
**4、访问来源IP地址异常:**正常情况下用户在查询、购买时,用户的IP地址比较稳定,而且访问来源IP比较;“爬虫”、“虚假占座”等操作时,IP来源地址呈现不同维度上的聚集,而且浏览、查询、购票等操作时不停变化IP地址。
5、设置UA模拟浏览器和频繁使用代理IP:很多“爬虫”程序伪装成浏览器进行访问,比如在程序头或者UA中默认含有类似python-requests/2.18.4等固定字符串;并且通过购买或者租用的云服务、改造路由器、租用IP代理、频繁变更代理IP等进行访问。
6、操作多集中非业务时间段:“爬虫”程序运行时间多集中在无人值守阶段。此时系统监控会放松,而且平台的带宽等资源占用少,爬虫密集的批量爬取不会对带宽、接口造成影响。以下是顶象反欺诈中心监测到,凌晨1-5点是恶意“爬虫”的运行高峰时段。
浅谈防范措施
1.设备指纹的应用
设备指纹单独用的话,在恶意爬虫面前,会稍微较弱一些。因为攻击者会使用其他技术手段来绕过设备指纹的检测,例如使用虚拟机、代理服务器等来隐藏真实设备的指纹。所以可以考虑结合IP地址限制一起使用:
import fingerprintjs2
from flask import Flask, request, abort
app = Flask(__name__)
# 创建一个新的Fingerprint2实例
fp = fingerprintjs2.Fingerprint2()
# 白名单IP地址
IP_WHITELIST = ['127.0.0.1', '192.168.0.1']
@app.route('/book-flight')
def book_flight():
# 获取设备指纹和IP地址
device_fingerprint = fp.get()
ip_address = request.remote_addr
# 检查IP地址是否在白名单中
if ip_address not in IP_WHITELIST:
abort(403)
# 其他业务逻辑代码...
return "Flight booked successfully!"
if __name__ == '__main__':
app.run()
2. 人机验证
人机验证肯定是一个阻挡办法,但是在这种恶意强攻击的情况下,我们可以试试语音验证码(但是可能对用户体验不大友好):
from flask import Flask, request, jsonify
import random
from io import BytesIO
from captcha.audio import AudioCaptcha
app = Flask(__name__)
# 生成随机字符串作为验证码
def random_string(length):
pool = 'abcdefghijklmnopqrstuvwxyz0123456789'
return ''.join(random.choice(pool) for i in range(length))
# 生成语音验证码
def generate_audio_captcha():
captcha = random_string(4)
audio = AudioCaptcha().generate(captcha)
return captcha, audio
# 创建一个全局变量,用于保存已生成的语音验证码
captcha_cache = {}
@app.route('/audio-captcha')
def audio_captcha():
# 生成新的语音验证码
captcha, audio = generate_audio_captcha()
# 将验证码保存到缓存中,以便后续验证
captcha_cache[captcha] = True
# 返回语音验证码
response = BytesIO(audio.read())
response.headers['Content-Type'] = 'audio/wav'
return response
@app.route('/book-flight', methods=['POST'])
def book_flight():
# 获取表单中的验证码
captcha = request.form['captcha']
# 检查验证码是否正确
if captcha not in captcha_cache:
return 'Invalid captcha!'
# 其他业务逻辑代码...
return "Flight booked successfully!"
if __name__ == '__main__':
app.run()
因为对用户体验不大友好,研发同学在设计的时候,最好考虑一下它的易用性和可访问性问题。需要权衡用户体验和恶意爬虫。
结语
“天下熙熙皆为利来,天下攘攘皆为利往。”因为这一块存在着巨大的利益,也就一直吸引着无数黑客从中牟利,而我们能做的,是“魔高一尺道高一丈”,希望能为安全世界尽一份力。
说个事情:滑动验证码 免 费