Day 27:【99天精通Python】HTTP协议与Requests库 - 爬虫与API的敲门砖
前言
欢迎来到第27天!
在昨天的课程中,我们用 Socket 写了一个简易的聊天程序。虽然很酷,但你有没有发现:为了发一句 “Hello”,我们写了几十行代码,还要处理复杂的粘包、断开连接等底层问题。
在当今的互联网世界,90% 以上的数据传输都建立在HTTP 协议之上(比如浏览网页、刷手机APP、调用API接口)。如果我们每次都用 Socket 去手写 HTTP 报文,那得累死。
Python 之所以被称为"爬虫神器"和"胶水语言",很大程度上归功于一个第三方库——Requests。它的口号是“HTTP for Humans”(给人类用的 HTTP 库)。今天,我们就来学习如何用最优雅的姿势上网。
本节内容:
- HTTP 协议基础 (请求与响应)
- Requests 库安装与入门
- 发送 GET 和 POST 请求
- 伪装请求头 (User-Agent)
- 处理响应数据 (文本、JSON、图片)
- 实战练习:下载图片与调用 API
一、HTTP 协议:互联网的快递单
在写代码前,我们得先看懂浏览器是怎么工作的。
当你在浏览器输入www.baidu.com并回车时,实际上发生了一次请求 (Request)和响应 (Response)的对话。
1.1 请求 (Request)
浏览器发给服务器的"快递单",包含:
- 方法 (Method):
GET: 我要拿数据 (如浏览网页)。POST: 我要提交数据 (如登录、发帖)。
- URL: 目标地址。
- 请求头 (Headers): 附加信息 (我是什么浏览器、我能看懂中文等)。
- 请求体 (Body): POST请求时携带的具体数据。
1.2 响应 (Response)
服务器回给你的包裹,包含:
- 状态码 (Status Code):
200: 成功 (OK)。403: 禁止访问 (Forbidden)。404: 找不到资源 (Not Found)。500: 服务器崩了 (Server Error)。
- 响应头 (Headers): 数据类型、长度等。
- 响应体 (Body): 具体的 HTML 网页代码、图片二进制数据或 JSON 数据。
二、Requests 库初体验
Requests 是第三方库,需要先安装:
pipinstallrequests2.1 最简单的 GET 请求
importrequests# 1. 发送请求url="https://www.baidu.com"response=requests.get(url)# 2. 查看状态码print(f"状态码:{response.status_code}")# 200# 3. 设置编码 (防止中文乱码)response.encoding="utf-8"# 4. 获取网页源代码 (文本)print(response.text[:100])# 打印前100个字符三、发送带参数的请求
3.1 GET 请求带参数 (params)
比如我们在百度搜索 “Python”,URL 会变成baidu.com/s?wd=Python。
# 不用手动拼 URL,requests 会自动处理params={"wd":"Python","ie":"utf-8"}resp=requests.get("https://www.baidu.com/s",params=params)print(resp.url)# 输出: https://www.baidu.com/s?wd=Python&ie=utf-83.2 POST 请求带数据 (data/json)
模拟表单提交(如登录)。
data={"username":"admin","password":"123"}# 表单提交 (application/x-www-form-urlencoded)resp=requests.post("http://httpbin.org/post",data=data)# JSON 提交 (application/json)resp_json=requests.post("http://httpbin.org/post",json=data)四、伪装自己:请求头 (Headers)
很多网站有反爬虫机制,如果发现你是 Python 程序(默认 User-Agent 是python-requests/x.x),会直接拒绝访问(返回 403)。
我们需要把自己伪装成浏览器。
headers={# 这是一个 Chrome 浏览器的 User-Agent"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}resp=requests.get("https://www.douban.com",headers=headers)print(resp.status_code)# 如果不加 headers 可能是 418 或 403,加上后是 200五、处理响应内容
服务器返回的数据不一定是文本,还可能是图片、视频或 JSON。
5.1 获取 JSON 数据
调用 API 接口时,返回的通常是 JSON。
# GitHub 的公开 APIurl="https://api.github.com/events"resp=requests.get(url)# 自动解析 JSON 为 Python 列表/字典data=resp.json()print(f"最近一条动态类型:{data[0]['type']}")5.2 获取二进制数据 (下载图片)
图片、音频、视频都是二进制数据,存储在response.content中。
img_url="https://www.python.org/static/img/python-logo.png"resp=requests.get(img_url)# 保存图片withopen("python_logo.png","wb")asf:f.write(resp.content)print("图片下载成功!")六、实战练习
练习1:简易网页采集器
编写一个程序,让用户输入一个关键词,程序自动去百度搜索,并将搜索结果页面的 HTML 保存到本地result.html中。
importrequestsdefbaidu_search(keyword):url="https://www.baidu.com/s"headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"}params={"wd":keyword}try:resp=requests.get(url,params=params,headers=headers)ifresp.status_code==200:filename=f"{keyword}_result.html"withopen(filename,"w",encoding="utf-8")asf:f.write(resp.text)print(f"搜索结果已保存至{filename}")else:print(f"请求失败,状态码:{resp.status_code}")exceptExceptionase:print(f"发生错误:{e}")# baidu_search("Python教程")练习2:IP地址查询 (调用 API)
使用免费的 IP 查询接口(如http://ip-api.com/json/),查询本机或者指定 IP 的地理位置信息。
importrequestsdefget_ip_info(ip=""):# 如果 ip 为空,接口默认查询本机url=f"http://ip-api.com/json/{ip}"try:resp=requests.get(url)data=resp.json()ifdata['status']=='success':print(f"IP:{data['query']}")print(f"国家:{data['country']}")print(f"城市:{data['city']}")print(f"ISP:{data['isp']}")else:print("查询失败")exceptExceptionase:print(f"网络错误:{e}")# get_ip_info() # 查本机# get_ip_info("8.8.8.8") # 查 Google DNS七、常见问题
Q1:超时了怎么办?
网络请求可能因为各种原因卡死。建议总是加上timeout参数。
# 3秒连不上就报错requests.get(url,timeout=3)Q2:SSL 证书验证错误?
访问 https 网站有时会报SSLError。可以设置verify=False忽略验证(不推荐在生产环境用)。
requests.get("https://unsafe-site.com",verify=False)Q3:如何保持登录状态?
使用requests.Session()。它会自动在多次请求之间保持 Cookies。
s=requests.Session()s.post("http://site.com/login",data=login_data)# 第一次请求登录s.get("http://site.com/profile")# 第二次请求会自动带上 Cookie八、小结
关键要点:
- Requests是 Python HTTP 操作的首选库。
- 爬虫第一步:记得加User-Agent伪装。
resp.text看网页源码,resp.content下载图片,resp.json()读接口数据。
九、课后作业
- 壁纸下载器:找到一个提供随机图片的 API(如
https://picsum.photos/200/300),循环下载 5 张图片并保存到本地images文件夹中。 - 天气查询工具:寻找一个免费的天气 API,编写程序输入城市名,输出该城市当前的天气情况。
- 状态检查员:有一个网站列表
urls = ["baidu.com", "google.com", "qq.com"],循环检测它们是否能正常访问(状态码200),并打印耗时。
下节预告
Day 28:HTML 解析库 BeautifulSoup- 拿到了网页源码(全是 HTML 标签)怎么提取里面的文字和链接?别用正则硬啃了,用 BeautifulSoup 像喝汤一样简单!
系列导航:
- 上一篇:Day 26 - 网络编程入门
- 下一篇:Day 28 - HTML解析库BeautifulSoup(待更新)