Python爬虫 5.requests发送请求与常见参数详解


一、为什么还要学习 requests

在前面的章节中,我们已经学习了如何使用 urllib 发送请求。

但是 urllib 的写法相对底层:

  • 需要手动构造 Request 对象
  • 需要手动处理编码
  • 代码相对繁琐

而在实际开发中,我们更希望:

  • 写更少的代码
  • 更直观地发送请求
  • 更方便地处理参数、请求头、Cookie

requests 正是为了解决这些问题而设计的。

可以简单理解为:

  • urllib:底层工具
  • requests:工程级工具(更常用)

为了更直观理解差异,可以对比一个简单请求:

# urllib 写法(简化示例)
from urllib import request

# 构造请求对象
req = request.Request('https://www.baidu.com')

# 发送请求并获取响应
res = request.urlopen(req)

# 读取内容(字节)
html = res.read()
# requests 写法
import requests

# 一行完成请求
res = requests.get('https://www.baidu.com')

# 直接获取文本
html = res.text

可以看到 requests 在可读性和简洁性上更有优势。


二、requests 是什么

requests 是 Python 中一个用于发送 HTTP 请求的第三方库。

它的核心作用是:

  • 向服务器发送请求
  • 接收服务器返回的数据

相比 urllib,它的优势在于:

  • API 简洁
  • 代码更易读
  • 内置很多常用功能(参数、Cookie、代理等)

常见的 HTTP 方法包括:

  • GET:获取数据(最常见)
  • POST:提交数据(表单、接口)
  • PUT/PATCH:更新数据
  • DELETE:删除数据

在爬虫中,最常用的是 GET 和 POST。


三、安装 requests

pip install requests

安装完成后,可以测试:

# 导入 requests 模块
import requests

如果没有报错,说明安装成功。

建议在虚拟环境中安装:

python -m venv venv
source venv/bin/activate  # macOS / Linux
pip install requests

四、第一个 requests 程序

# 导入 requests
import requests

# 定义目标网址
url = 'https://www.baidu.com'

# 发送 GET 请求
response = requests.get(url)

# 获取网页内容(字符串形式)
text = response.text

# 输出内容
print(text)

执行流程说明

  1. 导入 requests
  2. 定义 URL
  3. 调用 get() 发送请求
  4. 获取返回结果(Response 对象)
  5. 读取内容

可以简单检查请求是否成功:

# 状态码判断
if response.status_code == 200:
    print('请求成功')
else:
    print('请求失败,状态码:', response.status_code)

也可以使用:

# 若状态码不是 2xx 会抛异常
response.raise_for_status()

五、Response 对象详解

# 导入 requests
import requests

# 发送请求
response = requests.get('https://www.baidu.com')

# 获取文本内容(已解码)
print(response.text)

# 获取二进制内容
print(response.content)

# 获取状态码
print(response.status_code)

# 获取最终 URL
print(response.url)

# 获取响应头
print(response.headers)

# 查看编码
print(response.encoding)

如果接口返回的是 JSON 数据,也可以直接使用:

# 将响应内容直接解析为 Python 对象
print(response.json())

不过要注意:只有当服务器返回的内容本身就是 JSON 格式时,json() 才能正常使用。

重点说明

  • text:字符串(自动解码)
  • content:字节(适合图片/文件)
  • status_code:200 表示成功
  • url:最终访问地址(适合检查参数拼接结果)
  • headers:响应头信息
  • encoding:当前响应编码

如果页面出现乱码,可以手动设置编码:

response.encoding = 'utf-8'
print(response.text)

也可以查看服务器返回的编码:

print(response.apparent_encoding)

获取单个响应头:

print(response.headers.get('Content-Type'))

六、GET 请求详解

# 导入 requests
import requests

# 定义 URL
url = 'https://www.baidu.com/s'

# 定义参数
params = {
    'wd': 'Python'
}

# 定义请求头
headers = {
    'User-Agent': 'Mozilla/5.0'
}

# 发送 GET 请求
response = requests.get(url, params=params, headers=headers)

# 输出结果
print(response.text)

还可以通过 response.url 查看 requests 最终拼接出来的请求地址:

# 输出最终请求地址
print(response.url)

说明

  • params:自动拼接到 URL
  • headers:伪装浏览器
  • requests 会自动处理参数编码
  • 相比 urllib,不需要手动调用 urlencode()

params 也可以传入多个参数:

params = {
    'wd': 'Python',
    'pn': 10
}

设置超时时间:

response = requests.get(url, params=params, timeout=10)

七、POST 请求详解

# 导入 requests
import requests

# 接口地址
url = 'https://httpbin.org/post'

# POST 数据
data = {
    'username': 'test',
    'password': '123456'
}

# 发送 POST 请求
response = requests.post(url, data=data)

# 输出返回结果
print(response.text)

如果接口要求提交 JSON 数据,也可以使用 json 参数:

# 导入 requests
import requests

# 接口地址
url = 'https://httpbin.org/post'

# JSON 数据
json_data = {
    'username': 'test',
    'password': '123456'
}

# 发送 POST 请求,并以 JSON 格式提交
response = requests.post(url, json=json_data)

# 输出返回结果
print(response.text)

说明

  • data:POST 表单数据
  • POST 常用于提交数据
  • data 常用于普通表单提交
  • json 常用于接口请求

当使用 json= 时,requests 会自动设置:

Content-Type: application/json

如果使用 data=,通常是:

Content-Type: application/x-www-form-urlencoded

八、GET 与 POST 的区别

类型 GET POST
参数位置 URL 请求体
安全性 较低 较高
使用场景 查询 提交

九、Session(会话保持)

在多个请求之间共享 Cookie,可以使用 Session。

import requests

# 创建会话对象
session = requests.Session()

# 第一次请求(登录或设置 Cookie)
session.get('https://httpbin.org/cookies/set?name=python')

# 第二次请求会自动带上 Cookie
response = session.get('https://httpbin.org/cookies')
print(response.text)

适用于:

  • 登录后访问页面
  • 多次请求需要共享状态

十、代理参数 proxies

import requests

url = 'https://httpbin.org/ip'

proxies = {
    'http': 'http://127.0.0.1:7890',
    'https': 'http://127.0.0.1:7890'
}

response = requests.get(url, proxies=proxies)
print(response.text)

说明:

  • http 表示 HTTP 请求使用的代理
  • https 表示 HTTPS 请求使用的代理
  • 代理地址是否可用,会直接影响请求是否成功

也可以通过环境变量设置代理:

export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890

十一、Cookie 基础说明

import requests

url = 'https://httpbin.org/cookies'

cookies = {
    'name': 'python'
}

response = requests.get(url, cookies=cookies)
print(response.text)

说明:

  • Cookie 常用于保持登录状态
  • 某些网站如果不携带 Cookie,返回的页面内容可能不完整
  • requests 中可以直接通过字典传入 Cookie

有时需要从浏览器复制 Cookie:

headers = {
    'Cookie': 'name=python; sessionid=xxx'
}
response = requests.get(url, headers=headers)

十二、实战小案例

import requests

url = 'https://www.baidu.com/s'
params = {'wd': '爬虫'}

response = requests.get(url, params=params)

# 保存结果
with open('result.html', 'w', encoding='utf-8') as f:
    f.write(response.text)

下载图片示例:

import requests

url = 'https://httpbin.org/image/png'

# 获取二进制内容
response = requests.get(url)

# 写入文件
with open('image.png', 'wb') as f:
    f.write(response.content)

十三、常见问题

1. 乱码

response.encoding = 'utf-8'

2. 403

需要添加 headers。

3. 参数无效

检查 params / data 是否正确。

4. 接口返回的不是想要的数据

需要检查:

  • 请求方式是否正确(GET / POST)
  • 参数位置是否正确(params / data / json)
  • 是否缺少请求头
  • 是否需要携带 Cookie

5. 请求超时

可以设置超时时间:

response = requests.get(url, timeout=10)

这样可以避免程序长时间卡住。

6. 请求不稳定(建议重试)

import requests

for i in range(3):
    try:
        response = requests.get(url, timeout=5)
        response.raise_for_status()
        break
    except Exception as e:
        print('重试中...', i)

十四、补充:登录、验证码与代理排查思路

实际使用 requests 时,很多问题不是 requests.get()requests.post() 本身不会写,而是目标网站对登录态、验证码、频率、请求头做了限制。

1. 使用 Session 保持登录态

如果多个请求之间需要共享 Cookie,推荐使用 Session

import requests

session = requests.Session()

headers = {
    'User-Agent': 'Mozilla/5.0'
}

# 第一步:访问首页,让服务端下发初始 Cookie
session.get('https://example.com', headers=headers)

# 第二步:提交登录表单
data = {
    'username': 'user',
    'password': 'password'
}

session.post('https://example.com/login', headers=headers, data=data)

# 第三步:访问需要登录的页面
response = session.get('https://example.com/user', headers=headers)
print(response.text)

这里的重点不是账号密码,而是 session 会自动保存并携带 Cookie。

如果登录流程比较复杂,也可以先从浏览器中复制 Cookie,再放到请求头中测试。

headers = {
    'User-Agent': 'Mozilla/5.0',
    'Cookie': 'sessionid=xxx; token=xxx'
}

response = requests.get('https://example.com/user', headers=headers)

不过这种方式只适合临时测试。正式代码中不要把真实 Cookie 写死到文件里,更不要提交到 Git。

3. 验证码处理流程

遇到验证码时,建议先判断验证码在业务流程中的位置。

常见情况有三种:

场景 处理思路
普通图片验证码 下载验证码图片,人工输入或调用识别服务
滑块验证码 通常需要浏览器环境,更适合 Selenium
行为验证码 不建议强行绕过,应优先降低请求频率或使用人工流程

如果只是学习流程,可以把验证码处理拆成三步:

  1. 请求验证码图片。
  2. 保存到本地。
  3. 输入识别结果后再提交表单。

4. 代理是否生效的排查

配置代理后,建议先访问测试接口确认出口 IP。

import requests

proxies = {
    'http': 'http://127.0.0.1:7890',
    'https': 'http://127.0.0.1:7890'
}

response = requests.get(
    'https://httpbin.org/ip',
    proxies=proxies,
    timeout=10
)

print(response.text)

如果这里都访问失败,就不要继续排查业务网站了,应该先确认代理地址、端口、协议是否正确。


文章作者: hnbian
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hnbian !
评论
  目录