简介
欢迎来到「与 Web 应用交互」实验。在网络安全和 Web 自动化领域,以编程方式与 Web 应用进行交互是一项基本技能。无论是进行数据抓取、漏洞测试还是自动化重复性任务,你都需要一种可靠的方法来发送和接收 HTTP 请求。
在本实验中,你将学习如何使用功能强大的 Python requests 库。你将编写脚本来发送 HTTP GET 和 POST 请求、从服务器响应中提取关键信息、自动化表单提交,并管理会话 Cookie 以保持身份验证状态。
与原始套接字(raw sockets)相比,requests 工作在更高的抽象层级。它为你处理了许多 HTTP 细节,例如请求头、编码、重定向和 Cookie。这使得它非常适合安全自动化场景,因为在这些场景中,你更关注 Web 行为和工作流,而不是逐个数据包的底层机制。
发送 HTTP GET 请求
在这一步中,你将学习如何使用 Python 发送基本的 HTTP GET 请求。GET 方法用于从指定的资源请求数据,这与你在浏览器地址栏输入 URL 时请求网页的方式非常相似。
你可以将其视为 Web 自动化最简单的形式:请求资源并检查响应。许多侦察、测试和监控任务都是从这里开始的。
首先,确保你位于项目目录中。你将在该目录下创建本实验所需的所有 Python 脚本。
cd ~/project
现在,让我们创建一个 Python 脚本,向已为你准备好的本地 Web 服务器发送 GET 请求。使用 nano 文本编辑器创建一个名为 get_request.py 的文件:
nano get_request.py
在编辑器中输入以下 Python 代码:
import requests
url = 'http://127.0.0.1:5000/get'
response = requests.get(url)
print("Response Body:")
print(response.text)
保存文件并退出编辑器(在 nano 中,按 Ctrl+O,然后按 Enter 保存,按 Ctrl+X 退出)。
上述代码导入了 requests 库,定义了目标 URL,并使用 requests.get() 函数发送请求。服务器的响应存储在 response 变量中,我们打印出响应体的原始文本。
使用 Python 解释器运行你的脚本:
python3 get_request.py
你应该会看到类似以下的输出:
Response Body:
{"message":"GET request successful"}
提取 HTTP 状态码和响应头
在这一步中,你将学习如何从 HTTP 响应中提取更详细的信息,特别是状态码和响应头。
响应体只是信息的一部分。状态码告诉你服务器如何理解该请求,而响应头则描述了元数据,例如内容类型、缓存策略、Cookie 或服务器软件。优秀的自动化脚本会同时关注这三个层面:状态码、响应头和响应体。
当服务器响应 HTTP 请求时,它会包含一个状态码(例如 200 表示成功,404 表示未找到)以及提供响应元数据的响应头(例如内容类型或服务器软件)。
在项目目录中创建一个名为 check_status.py 的新文件:
nano check_status.py
将以下代码添加到文件中:
import requests
url = 'http://127.0.0.1:5000/get'
response = requests.get(url)
print(f"Status Code: {response.status_code}")
if response.status_code == 200:
print("The request was successful!")
print("\nResponse Headers:")
print(f"Content-Type: {response.headers.get('Content-Type')}")
print(f"Server: {response.headers.get('Server')}")
保存文件并退出编辑器。
在此脚本中,response.status_code 获取服务器返回的整数状态码。response.headers 是一个类似字典的对象,包含服务器返回的所有 HTTP 响应头。我们使用 .get() 方法来安全地提取特定的响应头。
运行脚本以查看提取的信息:
python3 check_status.py
你的输出应该如下所示:
Status Code: 200
The request was successful!
Response Headers:
Content-Type: application/json
Server: Werkzeug/3.0.1 Python/3.10.12
自动化表单提交 (POST)
在这一步中,你将学习如何发送 HTTP POST 请求。与用于获取数据的 GET 请求不同,POST 请求用于向服务器发送数据。这通常用于提交 Web 表单,例如登录凭据。
这种区别反映了 HTTP 的语义。在实践中,GET 通常用于读取资源,而 POST 通常用于提交或更改状态的操作。理解这种差异有助于你预测应用的行为以及你的脚本应如何与之交互。
我们将编写一个脚本来模拟提交带有用户名和密码的登录表单。
创建一个名为 post_request.py 的新文件:
nano post_request.py
输入以下代码:
import requests
url = 'http://127.0.0.1:5000/post'
## Define the form data as a dictionary
form_data = {
'username': 'admin',
'password': 'secret'
}
## Send the POST request with the data parameter
response = requests.post(url, data=form_data)
print(f"Status Code: {response.status_code}")
print(f"Response Body: {response.text}")
保存文件并退出编辑器。
在这里,我们定义了一个名为 form_data 的字典,其中包含我们的凭据。然后我们使用 requests.post() 并将字典传递给 data 参数。requests 库会自动将此数据格式化为标准的 Web 表单提交。
运行脚本以提交表单:
python3 post_request.py
你应该会看到一条登录成功的消息:
Status Code: 200
Response Body: {"message":"Login successful"}
你可以尝试将脚本中的密码更改为错误的值(例如 wrongpass)并再次运行,看看服务器如何返回 401 Unauthorized(未授权)状态码。
管理会话 Cookie
在最后一步中,你将学习如何管理会话 Cookie。HTTP 是一种无状态协议,这意味着每个请求都是独立的。为了在用户登录后记住他们,Web 应用会使用 Cookie。
如果你直接使用 requests.get() 或 requests.post(),Cookie 不会在请求之间保存。要维护会话(例如保持登录状态),你必须使用 requests 库提供的 Session 对象。
创建一个名为 session_request.py 的文件:
nano session_request.py
添加以下代码:
import requests
## Create a Session object
session = requests.Session()
login_url = 'http://127.0.0.1:5000/login'
profile_url = 'http://127.0.0.1:5000/profile'
print("Attempting to access profile BEFORE login...")
response1 = session.get(profile_url)
print(f"Status: {response1.status_code}, Body: {response1.text.strip()}")
print("\nLogging in to establish a session...")
## The session object will automatically store cookies returned by the server
session.post(login_url)
print("\nAttempting to access profile AFTER login...")
## The session object will automatically send the stored cookies with this request
response2 = session.get(profile_url)
print(f"Status: {response2.status_code}, Body: {response2.text.strip()}")
保存文件并退出编辑器。
在此脚本中,requests.Session() 创建了一个持久会话。当我们向 /login 发送 POST 请求时,服务器会设置一个会话 Cookie。Session 对象会存储此 Cookie,并在随后的 /profile GET 请求中自动包含它,从而允许我们访问受保护的路由。
运行脚本:
python3 session_request.py
观察输出。你会发现第一次尝试失败了,因为我们没有登录;但第二次尝试成功了,因为会话 Cookie 被自动管理了:
Attempting to access profile BEFORE login...
Status: 401, Body: {"message":"Unauthorized"}
Logging in to establish a session...
Attempting to access profile AFTER login...
Status: 200, Body: {"message":"Welcome to your profile!"}
总结
你已经学习了如何使用 Python 的 requests 库来实现 Web 交互自动化。你从发送基本的 HTTP GET 请求并提取状态码和响应头等重要元数据开始,进而学习了如何发送 HTTP POST 请求以自动化表单提交。最后,你掌握了如何使用 Session 对象来管理 Cookie,并在多个请求之间保持身份验证状态。
这些技能构成了 Web 抓取、API 集成和自动化安全测试中许多高级任务的基础。



