五一在即:有哪些办法能阻止票贩子和我们一起抢票?

2,660 阅读4分钟

背景

五一就要来了,本来准备去淄博吃烧烤,结果发现根本抢不到机票。了解了一下原因,原来是黄牛的恶意爬虫把票都抢完了,现在买票,只能通过黄牛的渠道,多花几倍的钱来买了。

有鉴于此,想试试能不能针对这种爬虫防止相关问题,当然是站在航空公司的角度,就个人而言,躺平任嘲就得了。

恶意爬虫的相关特征

对于恶意爬虫的特征,航空公司自己有总结:

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()

因为对用户体验不大友好,研发同学在设计的时候,最好考虑一下它的易用性和可访问性问题。需要权衡用户体验和恶意爬虫。

结语

“天下熙熙皆为利来,天下攘攘皆为利往。”因为这一块存在着巨大的利益,也就一直吸引着无数黑客从中牟利,而我们能做的,是“魔高一尺道高一丈”,希望能为安全世界尽一份力。

说个事情:滑动验证码 免 费 用