反爬风控设计之请求头顺序检测

本次主要讲解请求头的顺序检测的反爬实现,

如下使用Django写的headers请求头顺序检验算法:

def index(request):
    # 获取请求头的顺序
    request_order = list(request.META.keys())
    print(request_order)

    # 定义标准请求头顺序
    standard_order = [
        "HTTP_HOST",
        "HTTP_CONNECTION",
        "HTTP_USER_AGENT",
        "HTTP_ACCEPT_ENCODING",
        "HTTP_ACCEPT_LANGUAGE"
    ]

    # 检查标准请求头是否存在并按顺序排列
    start_index = 0
    for standard_header in standard_order:
        try:
            # 找到当前标准头的索引
            current_index = request_order.index(standard_header, start_index)
            # 更新起始索引,确保后续标准头在此索引之后
            start_index = current_index + 1
        except ValueError:
            # 如果找不到当前标准头,返回失败
            return HttpResponse("failed")

    # 如果所有标准请求头都在正确的顺序中
    return HttpResponse("success")

在浏览器端访问正常

在这里插入图片描述

在浏览器抓包复制 curl 生成python请求代码;

import requests


headers = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "Accept-Language": "zh,zh-CN;q=0.9",
    "Cache-Control": "no-cache",
    "Connection": "keep-alive",
    "Pragma": "no-cache",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
}
url = "http://127.0.0.1:8080/index"
response = requests.get(url, headers=headers, verify=False)

print(response.text)
print(response)

在这里插入图片描述

这样请求会失败,然后试着按上面的后端逻辑改一下请求头

 headers = {
        'Host': '127.0.0.0.1:8080',  # HTTP_HOST
        'Connection': 'keep-alive',  # HTTP_CONNECTION
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
        # HTTP_USER_AGENT
        'Accept-Encoding': 'gzip, deflate, br',  # HTTP_ACCEPT_ENCODING
        'Accept-Language': 'en-US,en;q=0.9',  # HTTP_ACCEPT_LANGUAGE
    }

发现还是失败的,在服务端打印请求日志发现实际上requests请求的时候请求头并没有按指定的顺序来,

在使用 requests 库时,确保请求头在发送时的顺序并非总能如预期那样实现,尤其是因为 HTTP 规范本身并不要求请求头的顺序。因此,尽管我们在代码中按照一定顺序添加头部,实际发送的 HTTP 请求可能并不遵循这个顺序。

解决方案

  1. 使用 http.client 进行更底层的控制:如果你必须确保请求头的顺序,http.clienthttpx 将是更好的选择。以下是使用 http.client 的示例:
import http.client

# 目标主机
host = "127.0.0.1:8080"

# 创建 HTTP 连接
conn = http.client.HTTPConnection(host)

# 构造请求头,确保顺序
headers = {
    'Host': '127.0.0.1:8080',  # HTTP_HOST
    'Connection': 'keep-alive',     # HTTP_CONNECTION
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',  # HTTP_USER_AGENT
    'Accept-Encoding': 'gzip, deflate, br',  # HTTP_ACCEPT_ENCODING
    'Accept-Language': 'en-US,en;q=0.9'       # HTTP_ACCEPT_LANGUAGE
}

# 发送请求
conn.request("GET", "/", headers=headers)

# 获取响应
response = conn.getresponse()

# 打印状态码和响应内容
print(response.status)
print(response.read().decode())

# 关闭连接
conn.close()
  1. 使用 httpx:如果你希望使用更现代的库,httpx 是一个更好的选择,它支持异步请求和更强大的功能。
    以下是使用 httpx 的示例:
import httpx

url = 'http://127.0.0.1:8080/'

# 构造请求头,确保顺序
headers = [
    ('Host', '127.0.0.1:8080'),   # HTTP_HOST
    ('Connection', 'keep-alive'),      # HTTP_CONNECTION
    ('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'),  # HTTP_USER_AGENT
    ('Accept-Encoding', 'gzip, deflate, br'),  # HTTP_ACCEPT_ENCODING
    ('Accept-Language', 'en-US,en;q=0.9')       # HTTP_ACCEPT_LANGUAGE
]

# 发送请求
response = httpx.get(url, headers=dict(headers))

# 打印状态码和响应内容
print(response.status_code)
print(response.text)

注意事项

  • HTTP 规范:HTTP 规范不保证请求头的顺序对于所有服务器都是重要的。大多数服务器会正确处理请求,即使请求头的顺序不同。

  • 调试信息:如果你在请求时遇到问题,可以通过调试或查看服务器的日志信息来获取更多线索。

  • 测试不同的库:如果请求仍然不如预期,可以尝试使用不同的库(如 http.clienthttpx)以验证问题是否与 requests 相关。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰履踏青云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值