说起Python发送HTTP请求,这可真是一个老生常谈,却又永不过时的话题。你有没有过那种,想从某个网站抓取点数据,或者想调个API接口却束手无策的经历?我告诉你,我当年刚入行那会儿,面对这些,真是两眼一抹黑,感觉就像是站在一座高耸入云的数字图书馆面前,却连门把手都摸不着。那时候,你用Python,面对的可能是那些晦涩难懂的标准库 urllib,每次敲代码都像是解一道数学题,弯弯绕绕,生怕哪里漏了一步就前功尽弃。那种挫败感,啧啧,现在回想起来,还真有点“往事不堪回首月明中”的意味。

但好在,时代变了,工具也越来越趁手。如今,我们有了一个几乎可以称之为“神器”的库,那就是 requests。每当我看到新手们还在urllib的泥潭里挣扎,我总想拍拍他们的肩膀,语重心长地说一句:“孩子,requests才是你的光明大道啊!”它简直就是为了我们这些懒人,或者说,为了让代码更像人话而生。用它发HTTP请求,那感觉,就像是把一堆复杂的齿轮,换成了只需轻轻一按的按钮,丝滑,流畅,舒服得不得了。

咱们先从最基础的,也是最常见的GET请求说起吧。你想访问一个网页,或者从某个API获取数据,九成九都是GET请求。用requests来搞定它,简直不要太简单。

“`python
import requests

访问一个普通的网页

url = ‘https://www.baidu.com’
try:
response = requests.get(url)
# 检查状态码,200意味着成功
if response.status_code == 200:
print(“访问百度成功!”)
# 打印响应内容的前几百个字符,看看是不是我们想要的
print(response.text[:500])
else:
print(f”访问百度失败,状态码:{response.status_code}”)
except requests.exceptions.RequestException as e:
print(f”请求过程中发生错误:{e}”)
“`

看到没?短短几行代码,一个GET请求就发出去了。requests.get(),多么直白,多么符合直觉!它返回的这个response对象,简直就是一个百宝箱,你想知道状态码,有response.status_code;想看响应头,有response.headers;想拿响应的文本内容,response.text直接奉上;如果是JSON数据,response.json()就能帮你完美解析,省去了你手动json.loads()的麻烦。那种一键到位的感觉,真是让人拍案叫绝。我刚开始用的时候,简直有点“相见恨晚”的感慨,所有的繁琐都一扫而空,只剩下代码逻辑的清晰。

当然,光是访问个静态页面那没什么意思,真正有用的地方在于,我们往往需要给请求带上参数。比如你想在某个电商网站搜索“手机”,或者在地图API里查询“上海天气”,这些都是通过URL参数来传递信息的。requests处理参数,同样优雅得不像话。你只需要把参数放进一个字典里,然后传给params参数就行了。

“`python

带参数的GET请求

search_url = ‘https://www.baidu.com/s’
params = {
‘wd’: ‘Python 发送 HTTP 请求’, # ‘wd’ 是百度搜索的关键词参数
‘ie’: ‘utf-8’ # 编码方式
}

try:
response = requests.get(search_url, params=params)
response.raise_for_status() # 如果状态码不是2xx,就抛出HTTPError异常
print(“\n搜索结果页面的部分内容:”)
print(response.text[:800])
except requests.exceptions.RequestException as e:
print(f”搜索过程中发生错误:{e}”)
“`

瞧瞧,这代码多干净利落!你甚至不需要关心这些参数最终是拼接在URL后面,还是做了URL编码,requests都帮你打理得妥妥帖帖。这种“你只管提要求,剩下的我来办”的态度,正是这个库最迷人的地方。

光有GET可不够,互联网世界里,POST请求才是数据提交的重头戏。无论是登录、注册、上传文件,还是提交表单,都离不开POST。requests处理POST请求,同样是信手拈来。数据可以是表单形式的(data参数),也可以是JSON形式的(json参数)。我个人偏爱用json参数,因为现在大部分现代API都偏向于JSON格式传输数据,干净,可读性强,比那些古老的application/x-www-form-urlencoded舒服多了。

“`python
import json

模拟POST请求,比如登录或提交数据

post_url = ‘https://httpbin.org/post’ # 这是一个用于测试的网站,会返回你发送的数据

模拟表单数据

form_data = {
‘username’: ‘your_python_user’,
‘password’: ‘your_secret_password’
}
print(“\n— 发送表单数据 —“)
try:
response = requests.post(post_url, data=form_data)
response.raise_for_status()
print(response.json()) # httpbin会把你的表单数据放在’form’字段里
except requests.exceptions.RequestException as e:
print(f”表单数据提交失败:{e}”)

模拟JSON数据

json_payload = {
‘title’: ‘Python Requests Tutorial’,
‘content’: ‘This is a great library for HTTP requests.’,
‘status’: ‘published’
}
print(“\n— 发送JSON数据 —“)
try:
# 注意这里用的是 json= 参数,requests会自动设置 Content-Type 为 application/json
response = requests.post(post_url, json=json_payload)
response.raise_for_status()
print(response.json()) # httpbin会把你的JSON数据放在’json’字段里
except requests.exceptions.RequestException as e:
print(f”JSON数据提交失败:{e}”)
“`

看看这两种POST方式,datajson,各有各的用武之地。requests聪明到,你用json=传字典时,它甚至会帮你自动设置Content-Type: application/json这个HTTP头部,省了你手动加的麻烦。这种“傻瓜式”的便捷,简直就是我们开发者梦寐以求的。

说到HTTP头部(Headers),这可是一个常常被新手忽略,但又至关重要的东西。HTTP请求就像一封信,而Header就是信封上那些额外的信息:发件人是谁(User-Agent),你想以什么格式接收(Accept),有没有带令牌(Authorization)等等。在做爬虫的时候,最常见的需求就是伪装User-Agent,让服务器误以为你是一个普通的浏览器,而不是一个冰冷的脚本。

“`python

自定义请求头

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’,
‘Accept’: ‘application/json, text/plain, /‘,
‘Referer’: ‘https://www.example.com/’, # 告诉服务器你是从哪里跳过来的
‘Authorization’: ‘Bearer your_access_token_here’ # 如果是API需要认证
}

target_url = ‘https://api.example.com/data’ # 假设这是一个需要认证的API
print(“\n— 带自定义请求头和授权的请求 —“)
try:
response = requests.get(target_url, headers=headers)
response.raise_for_status()
print(“请求成功,响应内容示例:”)
print(response.text[:300])
except requests.exceptions.RequestException as e:
print(f”请求失败:{e}”)
“`

你看,只要把一个字典塞给headers参数,所有自定义的HTTP头就都加上去了。这种灵活性,让requests能够应对各种复杂的场景,无论是模仿浏览器行为,还是处理API认证,都显得游刃有余。

不过,真实世界的网络环境可不像理想情况那么美好。网络可能会断开,服务器可能会忙得团团转,导致你的请求迟迟没有响应。这时候,超时(Timeout)就成了你的救星。设置一个合理的超时时间,可以防止你的程序无限期地等待一个没有响应的请求,避免资源耗尽。

“`python

设置超时

timeout_url = ‘https://httpbin.org/delay/5’ # 这个URL会延迟5秒响应

print(“\n— 测试超时机制 —“)
try:
# 设置超时时间为2秒,如果超过2秒没响应就抛异常
response = requests.get(timeout_url, timeout=2)
response.raise_for_status()
print(response.text)
except requests.exceptions.Timeout:
print(“请求超时了!等太久了,不等了!”)
except requests.exceptions.RequestException as e:
print(f”请求过程中发生错误:{e}”)
“`

我曾今就吃过没有设置超时的亏,一个简单的脚本,因为某个请求卡住了,结果整个程序就那么傻傻地挂在那里,直到我发现它停止了工作才去手动干预。那感觉,就像是你叫了一份外卖,结果外卖员迷路了,你却还在傻傻地等,手机都没电了才知道去催单。有了timeout,就好比你给外卖单加了一个“超过30分钟没到就自动取消”的选项,安心多了。

还有啊,我们经常会遇到需要保持会话(Session)的情况,比如登录网站后,后续的操作都需要依赖于登录状态(Cookie)。如果你每次请求都新建一个连接,那Cookie就没法传递了。这时候,requests.Session()就派上用场了。它能帮你自动处理Cookie、TCP连接复用等一系列复杂的问题,让你的多次请求就像是在同一个浏览器窗口里操作一样。

“`python

使用Session保持会话

session = requests.Session()

第一次请求,模拟登录(假设登录成功后会设置Cookie)

login_url = ‘https://httpbin.org/cookies/set/sessioncookie/123456789’
print(“\n— 第一次请求:设置Cookie —“)
try:
response = session.get(login_url)
response.raise_for_status()
print(“会话中的Cookie(第一次请求后):”, session.cookies.get(‘sessioncookie’))
except requests.exceptions.RequestException as e:
print(f”设置Cookie失败:{e}”)

第二次请求,会自动带上Session中保存的Cookie

check_url = ‘https://httpbin.org/cookies’
print(“\n— 第二次请求:检查Cookie是否自动带上 —“)
try:
response = session.get(check_url)
response.raise_for_status()
print(“会话中的Cookie(第二次请求后):”, response.json()[‘cookies’])
except requests.exceptions.RequestException as e:
print(f”检查Cookie失败:{e}”)
“`

Session啊,就像是一个贴心的管家,你每次通过它发送请求,它都会帮你把上一次请求中获得的Cookie保存下来,然后在下一次请求时自动带上。对于需要登录才能访问的资源,或者需要多次交互的API,这简直就是神来之笔,大大简化了代码逻辑。

最后,我想啰嗦几句。虽然requests强大得不像话,但我们在发送HTTP请求的时候,还是要牢记一些基本原则:

  1. 处理异常是王道: 永远不要相信网络是可靠的。try...except requests.exceptions.RequestException as e: 是你的好朋友。
  2. 检查状态码: response.status_coderesponse.raise_for_status()是判断请求是否成功的重要依据。我见过太多人,发了请求也不看状态码,结果数据没拿到还一脸懵圈。
  3. 做个文明的“网络公民”: 如果你在做爬虫,请注意目标网站的robots.txt文件,遵守网站的爬取规则。不要短时间内发起大量请求,给服务器造成过大压力,这不仅不道德,还可能导致你的IP被封,得不偿失。我当年年少轻狂,不懂这些,结果三天两头被网站封IP,那滋味,真是“悔不当初”!
  4. 调试工具: 当请求有问题时,Postman、Fiddler、Chrome开发者工具等都是你的利器。先用这些工具把请求调通,再把对应的参数、Header翻译成Python代码,事半功倍。

总而言之,Python发送HTTP请求,现在有了requests这个宝藏库,真是变得前所未有的简单和愉快。它把那些繁琐的网络通信细节都封装了起来,让你能更专注于业务逻辑,而不是在网络协议的泥沼里挣扎。从GET到POST,从参数到Header,从超时到会话,它都给出了优雅的解决方案。如果你还没用过它,那真的,赶紧去试试,你一定会爱上这种编码体验。我个人觉得,requests不仅仅是一个库,它更像是一种哲学,一种关于“如何让复杂的事情变得简单”的哲学。用Python发送HTTP请求,它就是你的不二之选,没有之一。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。