Skip to content

urllib与requests

学完 HTTP 基础以后,下一步就是用 Python 真正把请求发出去。

这一节的目标非常明确:让你从“知道请求是什么”,进入“能自己写代码请求网页和接口”的阶段。

本节目标

  • 理解 urllibrequests 的定位
  • 学会使用 requests 发送 GET 和 POST 请求
  • 学会传 URL 参数
  • 学会带请求头
  • 学会处理 JSON 响应
  • 学会理解 Session、Cookie 和代理的基础用法

urllibrequests 分别是什么

urllib

urllib 是 Python 自带的网络请求工具。

它的特点是:

  • 不需要额外安装
  • 更偏底层
  • 写法相对繁琐一些

学习它的意义主要在于:帮助你理解请求到底是怎么组织起来的。

requests

requests 是 Python 里非常常用的第三方请求库。

它的特点是:

  • 写法更友好
  • 可读性更高
  • 更适合初学者和日常项目

对于爬虫入门来说,你后面大多数时间都会先用它。

安装 requests

bash
pip install requests

安装完成后,你就可以开始发请求了。

第一个 GET 请求

python
import requests

url = "https://httpbin.org/get"
response = requests.get(url)

print(response.status_code)
print(response.text)

这里有几个关键点:

  • requests.get(url) 表示发 GET 请求
  • response.status_code 表示状态码
  • response.text 表示文本形式的响应内容

如果请求成功,状态码通常是:

text
200

response 对象里常用的内容

请求发出去以后,最重要的是会得到一个响应对象。

常用属性有:

  • response.status_code
  • response.text
  • response.content
  • response.headers
  • response.url

status_code

表示状态码。

text

表示字符串形式的响应内容,适合看 HTML 或文本。

content

表示字节形式的内容,适合处理图片、文件等二进制数据。

headers

表示响应头。

url

表示最终访问到的地址。

传 URL 参数

很多请求不是固定地址,而是带参数的。

例如搜索请求常见这种形式:

text
https://example.com/search?q=python&page=1

你可以这样写:

python
import requests

url = "https://httpbin.org/get"
params = {
    "kw": "python",
    "page": 1
}

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

print(response.url)

输出可能是:

text
https://httpbin.org/get?kw=python&page=1

这种写法比你手工拼字符串更规范,也更不容易写错。

POST 请求

很多登录、提交、接口调用会使用 POST。

python
import requests

url = "https://httpbin.org/post"
data = {
    "username": "tom",
    "password": "123456"
}

response = requests.post(url, data=data)

print(response.status_code)
print(response.text)

这里:

  • data 表示提交的数据
  • requests.post() 表示使用 POST 方法发送请求

JSON 响应处理

很多现代网站接口返回的不是 HTML,而是 JSON。

例如:

python
import requests

response = requests.get("https://httpbin.org/json")

print(response.json())

如果接口返回的是合法 JSON,这个方法会直接帮你转换成 Python 数据结构。

为什么 json() 很重要

因为接口类爬虫里,后面你经常要做这种事:

  • 请求接口
  • 获取 JSON
  • 从 JSON 中取字段

带请求头

很多网站会检查请求头,如果你什么都不带,可能直接不给你内容。

最常见要加的是 User-Agent

python
import requests

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

response = requests.get("https://httpbin.org/get", headers=headers)
print(response.status_code)

请求头为什么重要

因为服务器会通过请求头判断:

  • 你像不像正常浏览器
  • 你从哪里来
  • 你能接受什么类型的内容

常见请求头

User-Agent

标识客户端身份。

Referer

表示请求来源页面。

表示浏览器保存的会话或状态信息。

你在浏览器中登录一个网站后,再访问用户中心,通常不会每次都重新输入密码。这里背后常常就有 Cookie 和 Session 的作用。

python
import requests

cookies = {
    "sessionid": "abc123"
}

response = requests.get("https://example.com/profile", cookies=cookies)

这表示把指定 Cookie 带上一起请求。

Session 对象

如果你后续会连续发很多请求,并希望自动保持 Cookie,更常见的方式是用 Session

python
import requests

session = requests.Session()
session.headers.update({
    "User-Agent": "Mozilla/5.0"
})

response = session.get("https://httpbin.org/cookies/set?name=python")
print(response.status_code)

Session 的好处是:

  • 可以复用连接
  • 可以自动保存 Cookie
  • 更适合模拟连续访问流程

超时设置

做爬虫时,不要默认无限等待。

python
import requests

response = requests.get("https://httpbin.org/get", timeout=10)

这表示:

  • 最多等 10 秒
  • 超时就报错

这在真实项目里非常重要,否则程序可能一直卡住。

异常处理

网络请求很容易遇到问题,例如:

  • 连接失败
  • 超时
  • 目标网站挂了

所以要学会处理异常。

python
import requests

try:
    response = requests.get("https://httpbin.org/get", timeout=5)
    print(response.status_code)
except requests.RequestException as e:
    print("请求失败:", e)

代理设置

某些场景下,请求会通过代理服务器转发。

python
import requests

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

response = requests.get("https://httpbin.org/get", proxies=proxies)
print(response.status_code)

零基础阶段你先知道代理是什么、怎么写即可。后面反爬和高频请求时再更深入。

urllib 的一个基础示例

虽然实际中更常用 requests,但你也可以看一下 urllib 的基础写法。

python
from urllib import request

url = "https://httpbin.org/get"
response = request.urlopen(url)

print(response.status)
print(response.read().decode("utf-8"))

你会发现:

  • 能做同样的事情
  • 但写法相对更底层

这也是为什么很多入门教程更喜欢先教 requests

一个完整小案例:请求搜索接口并打印结果

python
import requests

url = "https://httpbin.org/get"
params = {
    "kw": "python crawler",
    "page": 1
}
headers = {
    "User-Agent": "Mozilla/5.0"
}

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

print("状态码:", response.status_code)
print("最终地址:", response.url)
print("返回内容:")
print(response.text)

这个例子已经把最常见的几步串起来了:

  • 传参数
  • 带请求头
  • 设置超时
  • 查看状态码
  • 查看返回结果

常见错误

1. 只看状态码,不看内容

有些网站即使返回 200,内容也可能是:

  • 登录页
  • 验证页
  • 空页面

2. response.textresponse.json() 混用

如果返回的是 HTML,就不应该乱用 json();如果返回的是 JSON,就优先用 json()

3. 不带请求头导致被拦

很多网站对没有浏览器标识的请求比较敏感。

4. 不写超时

这样一旦网络不稳定,程序可能长时间卡住。

练习题

练习 1

requests 发一个 GET 请求,打印状态码和返回文本。

练习 2

给请求加上 URL 参数,并打印最终请求地址。

练习 3

写一个 POST 请求,提交用户名和密码两个字段。

练习 4

请求一个返回 JSON 的地址,并用 response.json() 解析结果。

练习 5

尝试为请求添加 User-Agent,再加一个超时参数。

本节小结

这一节的核心,不是背 API,而是学会真正发出网络请求。

你最重要的收获应该是:

  • 会用 requests 发 GET 和 POST
  • 会传参数、带请求头、处理 JSON
  • 知道 Cookie、Session 和代理大概是干什么的
  • 知道请求时要考虑超时和异常处理

只要这一步扎实了,后面你再做页面抓取、接口分析和 Scrapy 项目时,就不会空转。

Built with VitePress.