Python中的HTTP访问利器
ztj100 2025-05-26 20:19 14 浏览 0 评论
Python里有不少能实现HTTP访问的利器,像requests库和urllib模块,用它们发起请求、处理响应超简单。
一、HTTP基础
HTTP(超文本传输协议)是Web通信的基础,它定义了客户端(如浏览器、Python程序)和服务器之间请求与响应的规则。一个完整的HTTP交互流程如下:
- 客户端发起请求:携带请求方法(如GET、POST)、URL、请求头、请求体等信息。
- 服务器处理请求:根据请求内容返回响应,包含状态码(如200表示成功)、响应头、响应体(如网页 HTML、JSON 数据)。
常见请求方法:
- GET:从服务器获取资源,常用于查询数据,请求参数附加在 URL 后。
- POST:向服务器提交数据,如表单提交、上传文件,参数在请求体中。
二、Python实现HTTP的访问
1. requests库:简洁高效的首选
requests库以简洁易用著称,只需几行代码就能完成HTTP请求。
安装:在命令行运行pip install requests。
基本使用(GET请求):
import requests
# 发送头条号网页的GET请求
params = {'key1': 'value1', 'key2': 'value2'}
response = requests.get('https://mp.toutiao.com', params=params,timeout=5)
# 检查响应状态码
if response.status_code == 200:
print("请求成功!")
print("响应内容(前50个字符):", response.text[:50])
else:
print(f"请求失败,状态码:{response.status_code}")
#输出为
请求成功!
响应内容(前50个字符): <!doctypehtml><html><head>
<script nonce='6bf7de99
基本使用(POST请求):
#post请求添加表单
data = {'username': 'user', 'password': '123456'}
response = requests.post('http://httpbin.org/post', data=data)
# 检查响应状态码
if response.status_code == 200:
print("请求成功!")
print("url:", response.url)
print("消息头:", response.headers)
print("消息体:", response.request.body)
print("响应内容(前50个字符):", response.text[:50])
else:
print(f"请求失败,状态码:{response.status_code}")
#输出为:
请求成功!
url: http://httpbin.org/post
消息头: {'Date': 'Sun, 27 Apr 2025 02:08:48 GMT', 'Content-Type': 'application/json', 'Content-Length': '510', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}
消息体: username=user&password=123456
响应内容(前50个字符): {
"args": {},
"data": "",
"files": {},
#post请求添加json数据
json_data = {'name': 'Alice', 'age': 25}
response = requests.post('http://httpbin.org/post', json=json_data)
# 检查响应状态码
if response.status_code == 200:
print("请求成功!")
print("url:", response.url)
print("消息头:", response.headers)
print("消息体:", response.request.body)
print("响应内容(前50个字符):", response.text[:50])
else:
print(f"请求失败,状态码:{response.status_code}")
#输出为:
请求成功!
url: http://httpbin.org/post
消息头: {'Date': 'Sun, 27 Apr 2025 02:08:48 GMT', 'Content-Type': 'application/json', 'Content-Length': '511', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}
消息体: b'{"name": "Alice", "age": 25}'
响应内容(前50个字符): {
"args": {},
"data": "{\"name\": \"Alice\",
关键函数与参数:
- requests.get(url, params=None, **kwargs):发送 GET 请求,params用于传递URL请求头的参数,timeout用于设置超时时间。
- requests.post(url, data=None, json=None, **kwargs):发送POST请求,data传递表单数据,json传递JSON数据。
- response.status_code:获取响应状态码。
- response.text:获取响应文本内容(字符串形式)。
- response.content:获取响应二进制内容(返回字节流,比如图片等非文本格式内容)。
- response.json():将响应内容解析为JSON对象(需响应为JSON格式)。
2. urllib模块:Python内置的 “老牌选手”
urllib是Python标准库的一部分,功能全面,适合更底层的HTTP操作。
基本使用(GET请求):
import urllib.request
#直接访问get请求
url = 'https://mp.toutiao.com'
try:
with urllib.request.urlopen(url) as response:
data = response.read().decode('utf-8')
print("请求成功!")
print("响应内容(前50个字符):", data[:50])
except urllib.error.URLError as e:
print(f"请求失败:{e}")
#添加请求头
req = urllib.request.Request(
url='https://mp.toutiao.com',
headers={'User-Agent': 'Mozilla/5.0'},
method='GET'
)
try:
with urllib.request.urlopen(req) as response:
data = response.read().decode('utf-8')
print("请求成功!")
print("响应内容(前50个字符):", data[:50])
except urllib.error.URLError as e:
print(f"请求失败:{e}")
基本使用(POST请求):
import urllib.request
from urllib.parse import urlencode
# 表单提交
data = urlencode({'user': 'admin', 'pass': 'secret'}).encode()
try:
with urllib.request.urlopen('http://httpbin.org/post', data=data) as response:
data = response.read().decode('utf-8')
print("请求成功!")
print("响应内容(前50个字符):", data[:50])
except urllib.error.URLError as e:
print(f"请求失败:{e}")
#输出为:
表单内容:b'user=admin&pass=secret'
请求成功!
响应内容(前50个字符): {
"args": {},
"data": "",
"files": {},
# JSON提交
import json
data = json.dumps({'id': 100}).encode('utf-8')
req = urllib.request.Request(
url='http://httpbin.org/post',
data=data,
headers={'Content-Type': 'application/json'}
)
try:
with urllib.request.urlopen(req) as response:
data = response.read().decode('utf-8')
print("请求成功!")
print("响应内容(前50个字符):", data[:50])
except urllib.error.URLError as e:
print(f"请求失败:{e}")
#输出为:
请求成功!
响应内容(前50个字符): {
"args": {},
"data": "{\"id\": 100}",
"fi
核心模块与函数:
- urllib.request.urlopen(url, data=None, **kwargs):打开 URL,data用于POST请求(需编码为字节流)。
- urllib.parse.urlencode将字典数据转换为key=value&key2=value2格式的字符串,并用encode('utf-8')将字符串转换为字节流,因为urlopen方法要求请求体是字节流。
- urllib.request.Request创建请求对象,将URL和请求体传入。
- urllib.error.URLError:捕获 URL 相关错误,如网络问题、服务器不可达。
- urllib.error.HTTPError:捕获 HTTP 响应错误(状态码非 200)。
3. aiohttp库:异步HTTP请求的 “快枪手”
aiohttp是用于异步I/O的HTTP客户端/服务器库,在处理大量并发请求时性能出色,特别适合异步编程场景,如爬虫、API 服务等。
安装:在命令行运行pip install aiohttp。
基本使用(异步GET请求):
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
"https://www.example1.com",
"https://www.example2.com",
"https://www.example3.com"
]
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
results = await asyncio.gather(*tasks)
for result in results:
print("响应内容(前50个字符):", result[:50])
asyncio.run(main())
核心函数与特点:
- aiohttp.ClientSession():创建客户端会话,用于管理 HTTP 连接。
- session.get(url, **kwargs) / session.post(url, **kwargs):发送 GET/POST 请求,支持异步操作。
- response.text():以文本形式获取响应内容,需配合await使用。
4. httpx库:集大成者
httpx结合了requests的简洁和aiohttp的异步功能,同时支持同步和异步请求,并且对HTTP/2协议有良好的支持。
安装:在命令行运行pip install httpx。
基本使用(GET请求):
import httpx
response = httpx.get('http://httpbin.org/')
if response.status_code == 200:
print("请求成功!")
print("响应内容(前50个字符):", response.text[:50])
else:
print(f"请求失败,状态码:{response.status_code}")
异步使用示例:
import asyncio
import httpx
async def async_fetch():
async with httpx.AsyncClient() as client:
response = await client.get('http://httpbin.org/')
if response.status_code == 200:
print("异步请求成功!")
print("响应内容(前50个字符):", response.text[:50])
else:
print(f"异步请求失败,状态码:{response.status_code}")
asyncio.run(async_fetch())
三、闭坑指南
请求超时问题
- 在requests中设置timeout参数,如response = requests.get(url, timeout=5)
- 在urllib中通过socket.setdefaulttimeout()设置全局超时。
- 在aiohttp中,可在请求时设置timeout=aiohttp.ClientTimeout(total=10) 。
- 在httpx中,同步请求使用httpx.get(url, timeout=5),异步请求使用await client.get(url, timeout=5)。
请求头缺失或错误
部分网站需要特定请求头(如User-Agent),缺失会导致请求被拒绝。在requests中通过headers参数添加请求头,如:
headers = { "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" } response = requests.get(url, headers=headers) |
- 在urllib中通过Request对象设置请求头:
req = urllib.request.Request(url, headers=headers)
- 在aiohttp中,在创建ClientSession时传入headers参数 ,如async with aiohttp.ClientSession(headers=headers) as session:。
- 在httpx中,同步和异步请求均可通过headers参数设置,如response = httpx.get(url, headers=headers) 、response = await client.get(url, headers=headers)。
响应内容解析错误
先通过response.headers.get('Content-Type')判断响应类型,再选择合适的解析方式。
SSL 证书验证问题
访问 HTTPS 网站时,证书验证失败导致请求中断。在requests中设置verify=False忽略证书验证(不建议在生产环境使用),或指定证书路径。在urllib中使用ssl模块处理证书。在aiohttp中,可通过connector=aiohttp.TCPConnector(ssl=False)忽略 SSL 验证(不推荐)。在httpx中,同步请求使用httpx.get(url, verify=False),异步请求使用await client.get(url, verify=False)(需谨慎使用)。
四、总结回顾
掌握Python的HTTP访问技能,无论是获取网页内容、调用API数据,还是与服务器交互,requests、urllib、aiohttp、httpx等库都能助你轻松完成。
附录、HTTP 访问常用函数汇总
库 / 模块 | 函数 / 方法 | 功能 |
requests | requests.get(url, params=None, **kwargs) | 发送 GET 请求 |
requests.post(url, data=None, json=None, **kwargs) | 发送 POST 请求 | |
response.status_code | 获取响应状态码 | |
response.text | 获取响应内容(字符串形式) | |
response.content | 获取响应内容(二进制形式) | |
response.json() | 将响应内容解析为 JSON 对象 | |
urllib.request | urllib.request.urlopen(url, data=None, **kwargs) | 打开 URL,发送请求 |
urllib.request.Request(url, data=None, headers=None, **kwargs) | 创建请求对象 | |
urllib.error.URLError | 捕获 URL 相关错误 | |
urllib.error.HTTPError | 捕获 HTTP 响应错误 | |
aiohttp | aiohttp.ClientSession() | 创建客户端会话 |
session.get(url, **kwargs) | 发送异步 GET 请求 | |
session.post(url, **kwargs) | 发送异步 POST 请求 | |
response.text() | 以文本形式获取响应内容 | |
httpx | httpx.get(url, **kwargs) | 发送同步 GET 请求 |
- 上一篇:python进阶突破——关闭流要点
- 下一篇:Python并发编程实用教程
相关推荐
- Spring IoC Container 原理解析
-
IoC、DI基础概念关于IoC和DI大家都不陌生,我们直接上martinfowler的原文,里面已经有DI的例子和spring的使用示例...
- SQL注入:程序员亲手打开的潘多拉魔盒,如何彻底封印它?
-
一、现象:当你的数据库开始"说话",灾难就来了场景还原:...
- Java核心知识3:异常机制详解
-
1什么是异常异常是指程序在运行过程中发生的,由于外部问题导致的运行异常事件,如:文件找不到、网络连接失败、空指针、非法参数等。异常是一个事件,它发生在程序运行期间,且中断程序的运行。...
- MyBatis常用工具类三-使用SqlRunner操作数据库
-
MyBatis中提供了一个非常实用的、用于操作数据库的SqlRunner工具类,该类对JDBC做了很好的封装,结合SQL工具类,能够很方便地通过Java代码执行SQL语句并检索SQL执行结果。SqlR...
- 爆肝2W字梳理50道计算机网络必问面试题
-
1.说说HTTP常用的状态码及其含义?思路:这道面试题主要考察候选人,是否掌握HTTP状态码这个基础知识点。...
- SpringBoot整合Vue3实现发送邮箱验证码功能
-
1.效果演示2.思维导图...
- 最全JAVA面试题及答案(200+)
-
Java基础1.JDK和JRE有什么区别?JDK:JavaDevelopmentKit的简称,Java开发工具包,提供了Java的开发环境和运行环境。JRE:JavaRunti...
- Java程序员找工作翻车现场!你的项目描述踩了这几个坑?
-
Java程序员找工作翻车现场!你的项目描述踩了这几个坑?噼里啪啦敲了三年代码,简历一投石沉大海?兄弟,问题可能出在项目描述上!知道为什么面试官看你的项目像看天书吗?因为你写了三个致命雷区:第一,把项目...
- 2020最新整理JAVA面试题附答案,包含19个模块共208道面试题
-
包含的模块:本文分为十九个模块,分别是:Java基础、容器、多线程、反射、对象拷贝、JavaWeb、异常、网络、设计模式、Spring/SpringMVC、SpringBoot/Spring...
- 底层原理深度解析:equals() 与 == 的 JVM 级运作机制
-
作为Java开发者,你是否曾在集合操作时遇到过对象比较的诡异问题?是否在使用HashMap时发现对象丢失?这些问题往往源于对equals()和==的误解,以及实体类中这两个方法的不当实...
- 雪花算法,什么情况下发生 ID 冲突?
-
分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的...
- 50个Java编程技巧,免费送给大家
-
一、语法类技巧1.1.使用三元表达式普通:...
- 如何规划一个合理的JAVA项目工程结构
-
由于阿里Java开发手册对于工程结构的描述仅限于1、2节简单的概述,不能满足多样的实际需求,本文根据多个项目中工程的实践,分享一种较为合理实用的工程结构。工程结构的原则有依据、实用。有依据的含义是指做...
- Java 编程技巧之单元测试用例编写流程
-
温馨提示:本文较长,同学们可收藏后再看:)前言...
- MyBatis核心源码解读:SQL执行流程的奇妙之旅
-
MyBatis核心源码解读:SQL执行流程的奇妙之旅大家好呀!今天咱们要来一场既烧脑又有趣的旅程——探索MyBatis这个强大框架的核心秘密。你知道吗?当你在项目里轻轻松松写一句“select*f...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)