资讯动态

Python Requests库入门实战演示

发布时间:2026/10/28 2:38:42 来源:尧图企业网站定制
前言requests是 Python 生态里最有名的第三方 HTTP 库它把标准库urllib那些绕来绕去的地方——手工编码参数、手工解码字节、手工管理连接——统统包成了带默认值的函数。写一行requests.get(url)参数、编码、连接复用都替你处理了。但它有个前提必须先说清楚requests不是标准库。import requests之前必须先pip install requests装不上就没法用。这和urllib随 Python 一起发布、零依赖是完全不同的定位。另外Python 2.7 已于2020 年 1 月 1 日停止维护requests也早已放弃对它的支持按 PyPI 上的元数据最新版requests声明requires_python为3.10所以在更老的 Python 3 上pip会自动挑一个兼容的旧版本装上。本文只做入门安装、get/post、params/data/headers三个最常用的关键字参数以及Response对象上那五个属性。会话保持、流式下载、重试这些放到进阶文章里讲。一、安装与第一个请求pip install requests如果机器上有多个 Python用python -m pip install requests更保险能保证装到当前解释器对应的环境里。装好后最简单的验证方式是发一个请求# 适用于 Python 3.8requests 本体请用 pip 安装import requestsr requests.get(https://example.com, timeout10)print(r.status_code) # 200print(type(r)) # class requests.models.Response官方的接口文档里写得很直白所有功能都通过 7 个模块级方法暴露request、get、head、post、put、patch、delete它们全部返回Response对象。也就是说你只要学会读懂一个Response七个方法就都会用了。timeout建议永远显式传。不传时 requests 会一直等下去服务端不响应就卡死这一点和urllib的默认行为一样但 requests 的文档反复强调过。二、get 与 paramsrequests.get()的签名是requests.get(url, paramsNone, **kwargs)params接受字典、元组列表或 bytesrequests 会替你编码并拼到问号后面。过程中不需要你碰urlencode。# 适用于 Python 3.8import requestsparams {q: python requests, page: 1}r requests.get(https://example.com/search, paramsparams, timeout10)print(r.url) # 实际发出的完整 URL参数已被编码拼好print(r.status_code)print(r.text[:200]) # 文本形式的响应体r.url是个被低估的属性它显示的是真正发出去的URL编码成什么样、有没有被重定向一看便知。调试参数编码问题时先看它。字典里如果某个值是Nonerequests 会把这个键整个丢掉不会传keyNone过去值如果是列表默认会展开成多个同名参数等价于urllib里的doseqTrue。三、postdata 与 json 的区别requests.post()的签名是requests.post(url, dataNone, jsonNone, **kwargs)data和json是两套不同的请求体编码方式用错了服务端多半解析不出来参数请求体内容自动设置的Content-Type适用场景datadict表单编码kvk2v2application/x-www-form-urlencoded传统表单提交jsondictJSON 文本application/json现代 REST 接口datastr原样发送字符串不自动设置需自己加头特殊格式的裸文本# 适用于 Python 3.8import requests# 表单风格r1 requests.post(https://example.com/api/login,data{username: alice, password: secret},timeout10,)print(r1.status_code)# JSON 接口风格r2 requests.post(https://example.com/api/items,json{name: book, price: 42},timeout10,)print(r2.status_code)注意json会顺带把请求头设成application/json而data传字典时设的是application/x-www-form-urlencoded。手工传data一个字符串时requests 不知道格式不会帮你设置Content-Type需要自己在headers里补。四、headers身份与内容协商headers是这七个方法共有的关键字参数传一个字典即可。爬取公开页面时最有用的两个头是User-Agent和Accept-Language。请如实标识自己# 适用于 Python 3.8import requestsheaders {User-Agent: page-reader/1.0 (contact: meexample.com),Accept-Language: zh-CN,zh;q0.9,}r requests.get(https://example.com/, headersheaders, timeout10)print(r.status_code)print(r.headers.get(Content-Type))自定义头会与 requests 自带的默认头合并你提供的同名键会覆盖默认值。这一点比urllib方便urllib里默认User-Agent是Python-urllib/3.x要改还得动 opener。顺便提一句合规底线真实可识别的 UA、请求之间time.sleep()限速、先看 robots.txt、只抓公开页面、不绕登录墙与验证码。这些是把requests当工具用而不是当武器用的分界线。五、Response 对象五个必须认识的东西Response上的属性很多入门阶段先掌握下面五个日常用法基本都在里面。# 适用于 Python 3.8import requestsr requests.get(https://example.com/, timeout10)print(r.status_code) # int例如 200 / 404print(r.ok) # status_code 400 时为 Trueprint(r.headers[Content-Type])print(r.encoding) # 用于解码 r.text 的编码名可能是 Noneprint(len(r.content)) # bytes响应体原始字节r.raise_for_status() # 4xx/5xx 时抛 requests.HTTPErrorstatus_code整数状态码。判断成功不要只看 200用r.ok它判断的是status_code 400或raise_for_status()更合适。text与contenttext是strcontent是bytes。要下载图片、压缩包这类二进制内容必须用content。encoding决定text怎么解码。requests 会先看 HTTP 头的Content-Type里有没有 charset官方的说法是如果Response.encoding是None它会用charset_normalizer之类的工具去猜。如果你知道真实编码就在访问text之前手动赋值例如r.encoding utf-8猜错的概率会低很多。json()把响应体按 JSON 解析成 Python 对象字典、列表等。解析失败会抛requests.exceptions.JSONDecodeError。# 适用于 Python 3.8import requestsr requests.get(https://example.com/api/item/1, timeout10)r.encoding utf-8 # 明确指定避免猜测data r.json() # 解析失败会抛 JSONDecodeErrorprint(type(data))print(data.get(name) if isinstance(data, dict) else len(data))还有一个容易忽略的r.history它是一个Response列表记录这次请求经过的重定向链从最早到最新排列。排查「为什么拿到的页面和我请求的不一样」时先看它是不是非空。常见坑点1. 忘了pip install就 import。❌import requests直接写在脚本开头换台机器就ModuleNotFoundError。 ✅ 先python -m pip install requests交付脚本时在说明里写明这项依赖或改用标准库urllib。2. 不传 timeout。❌requests.get(url)—— 服务端不响应就无限等。 ✅requests.get(url, timeout10)。需要更细的控制可以传(连接超时, 读取超时)元组。3. 用text拿二进制内容。❌open(a.png, wb).write(r.text)——str不是bytes写文件会失败。 ✅open(a.png, wb).write(r.content)。4. 拿到响应就访问text之后再改encoding。❌print(r.text)然后再r.encoding utf-8—— 第一次访问时已经按猜的编码解好了。官方文档明确要求要在访问text之前设置encoding。 ✅ 先r.encoding utf-8再r.text。5. POST 该传 JSON 时传了data字典。❌requests.post(url, data{a: 1})打 JSON 接口 —— 服务端按表单解析直接 400。 ✅requests.post(url, json{a: 1})Content-Type会自动变成application/json。6. 把status_code 200当作唯一成功判据。❌if r.status_code 200:—— 201、204 这些同样表示成功。 ✅ 用r.ok或r.raise_for_status()。7. 用r.json()解析非 JSON 响应。❌ 对 HTML 页面调r.json()—— 抛requests.exceptions.JSONDecodeError。 ✅ 先用r.headers.get(Content-Type)判断是不是 JSON或把调用放进try/except。8. 把r.text当字节长度统计。❌len(r.text)—— 字符数不等于字节数中文一个字在这里算 1。 ✅ 要字节数用len(r.content)。总结想做的事写法发 GETrequests.get(url, params{...}, headers{...}, timeout10)发 POST 表单requests.post(url, data{...})发 POST JSONrequests.post(url, json{...})取文本先设r.encoding再读r.text取字节r.content解析 JSONr.json()失败抛JSONDecodeError判断成功r.ok或r.raise_for_status()看真实 URLr.url、r.historyrequests上手快是因为默认值选得好但默认值也会掩盖行为比如编码猜错、超时无限、text与content混用。把这些默认值搞明白才算真的入了门。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑