CS 41 课程四:Python与网络编程(4月25日)
一、课程进度回顾
CS 41 课程概览
| 周次 | 主题 | 核心问题 |
|---|---|---|
| Week 1 | Python基础 | 如何在Python世界做基本操作?Python的哲学是什么? |
| Week 2 | 数据结构与面向对象 | 如何扩展Python功能? |
| Week 3 | 电子学 | 如何使用Python增强物理设备? |
| Week 4 | Python与网络 | 如何与互联网交互? |
期末项目时间表
- Week 5结束前:提交项目提案
- Week 7/8:与Parth/Tara会面讨论
- Week 10(5月31日):项目展示
二、课程引入:数据可视化案例
1. Dear Data项目
慕尼黑通勤延误可视化
- 一位女性记录2018年往返慕尼黑和德国乡村的40分钟通勤延误
- 每天编织两行:
- 灰色:延误少于5分钟
- 粉色:延误最多30分钟
- 红色:延误超过半小时或双向延误
- 来源:The New York Times
2. 情绪可视化
使用Spotify数据作为情绪代理
- 艺术性的聚合可视化
- 通过听歌数据反映个人情绪变化
- 来源:Reddit用户分享
3. 垃圾追踪项目
Rob Greenfield的"Trash Me"
- 网站:https://www.robgreenfield.org/trashme/
- 可视化个人垃圾产生情况
三、学习目标
学完本课后,学生应能够:
- 高层次描述网络请求的工作原理
- 查询API并将结果转换为Python对象;在请求中包含身份验证头
- 将这些查询集成到其他Python应用程序中
四、互联网工作原理
1. 网络基础概念
基本连接模型:
我的计算机 ←→ 互联网 ←→ 另一台计算机
IP地址示例:
我的计算机 目标计算机
128.12.123.184 → 172.217.5.110
2. IP地址结构
IP地址组成:
128.12.123.184
├─────┬─────┤├──┬──┤
网络标识符 主机标识符
3. DNS(域名系统)
域名解析过程:
- 用户在浏览器输入:
google.com - DNS将域名转换为IP地址:
172.217.5.110 - 请求被发送到Google服务器
4. 路由追踪(Traceroute)
命令示例:
bash
$ traceroute google.com
关键跳点分析:
traceroute to google.com (172.217.5.110), 64 hops max, 52 byte packets
1 sc-srtr-vl3566.sunet (128.12.72.1) 1.239 ms
2 res-press-mx240-temp-rtr.mgmt.sunet (192.168.190.164) 2.018 ms
3 xb-nw-rtr-vlan11.sunet (171.64.0.193) 0.947 ms
4 dc-svl-rtr-vl3.sunet (171.66.255.190) 1.860 ms
5 dc-svl-agg4--stanford-100ge.cenic.net (137.164.23.144) 2.958 ms
...
15 sfo03s07-in-f110.1e100.net (172.217.5.110) 12.449 ms
CENIC网络:
- 成立于1997年的非营利组织
- 运营加州研究与教育网络(CalREN)
- 超过8,000英里的光纤网络
- 服务加州超过2000万用户
- 包括K-20学生、教育工作者、研究人员等
五、HTTP请求详解
1. HTTP请求的组成
实际发送的内容:
http
GET / HTTP/2
Host: www.google.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:88.0)
Gecko/20100101 Firefox/88.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,
image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
TE: Trailers
组成部分:
- 请求方法和路径 :
GET / HTTP/2 - 请求头(Headers):包含客户端信息、接受的内容类型等
六、使用Python发起请求
1. requests库基础
简单GET请求:
python
import requests
# 基本GET请求,无请求头
r = requests.get(url)
带请求头的GET请求:
python
r = requests.get(
url,
headers={'Accept-Language': 'es'}
)
- 可以将请求头指定为字典
带查询参数的GET请求:
python
r = requests.get(
'https://www.google.com/search',
params={'q': 'unicorns'}
)
- 查询URL:
google.com/search?q=unicorns
POST请求:
python
r = requests.post(
url,
data={'key1': 'value1'}
)
- 不同类型的HTTP请求
七、解析响应数据
1. 网络数据格式
常见格式:
| 格式 | 说明 | 用途 |
|---|---|---|
| HTML | 为网络浏览器构建 | 大多数网页 |
| JSON | 将对象表示为字符串 | 通常不直接显示给用户 |
| Text | 原始文本 | 部分服务器响应 |
| Other | 图像、PDF等 | 各有自己的格式 |
2. JSON格式示例
笑话API响应:
json
{
"id": 317,
"type": "general",
"setup": "Why are oranges the smartest fruit?",
"punchline": "Because they are made to concentrate."
}
来源:https://official-joke-api.appspot.com/random_joke
3. 处理响应的三种方式
完整示例:
python
import requests
r = requests.get(
'https://official-joke-api.appspot.com/random_joke'
)
方式1:原始字节数据(bytes)
python
r.content
# => b'{"id":86,"type":"general","setup":"Did you hear about the bread
# factory burning down?","punchline":"They say the business is toast."}'
- 返回原始字节数据
方式2:字符串(string)
python
r.text
# => '{"id":86,"type":"general","setup":"Did you hear about the bread
# factory burning down?","punchline":"They say the business is toast."}'
- 返回字符串格式
方式3:Python字典(dictionary)
python
r.json()
# => {'id': 86,
# 'type': 'general',
# 'setup': 'Did you hear about the bread factory burning down?',
# 'punchline': 'They say the business is toast.'}
- 自动解析JSON为Python字典
- 最常用的方式
八、API详解
1. API定义
API = Application Programming Interface(应用程序编程接口)
核心特点:
- 应用程序(计算机程序)之间相互通信的方式
- 暴露的接口通常不是用户友好的,而是程序员友好的
- 其他程序可以接入并使用
示例:
2. API资源
课程提供:
- API资源清单(API Resource Sheet)
- 用于探索和实践
3. 实践项目
Secret Number游戏
- 通过API进行实际操作演示
九、补充材料:函数装饰器示例
缓存装饰器(Cache Decorator)
代码示例(来自Scratchpad):
python
import functools
import time
# 使用缓存的斐波那契函数
@functools.cache
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
# 不使用缓存的斐波那契函数(注意:代码中仍有@functools.cache)
def fibonacci_non_cache(n):
if n <= 1:
return n
return fibonacci_non_cache(n - 1) + fibonacci_non_cache(n - 2)
# 性能测试 - 缓存版本
start_time = time.time()
print(fibonacci(35))
end_time = time.time()
execution_time = end_time - start_time
print(f'Execution time (cached): {execution_time} seconds.')
# 测试更大的数
start_time = time.time()
print(fibonacci(50))
end_time = time.time()
execution_time = end_time - start_time
print(f"Execution time (cached): {execution_time} seconds")
# 非缓存版本对比
start_time = time.time()
print(fibonacci_non_cache(50))
end_time = time.time()
execution_time = end_time - start_time
print(f"Execution time FOR NON cached: {execution_time} seconds")
列表示例:
python
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
十、课程总结
核心概念
1. 互联网通信:
- IP地址:网络标识 + 主机标识
- DNS:域名到IP地址的转换
- 路由:数据包通过多个节点到达目的地
2. HTTP请求:
- 请求方法:GET、POST等
- 请求头:传递元数据
- 查询参数:传递数据
3. Python网络编程:
- 使用
requests库发起请求 - 处理响应:bytes、text、json
- JSON是最常用的API数据格式
4. API使用:
- API是程序间通信的接口
- 程序员友好,非用户友好
- 可以将外部数据集成到Python程序中
实践应用
典型工作流程:
- 导入requests库
- 发送HTTP请求(GET/POST)
- 接收响应对象
- 解析响应数据(通常用
.json()) - 在Python程序中使用数据
下一步:
- 探索各种公开API
- 将API数据集成到项目中
- 构建实际应用(如Secret Number游戏)