Pandas & NumPy Academy · 课时

从 URL 与 StringIO 读取

直接从 URL 加载远程 CSV 文件,并使用 io.StringIO 解析内存中的 CSV 字符串以进行测试。

第 4 / 4 课13 个步骤

从 URL 与 StringIO 读取 是 CoddyKit 上的免费 Pandas & NumPy Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Pandas & NumPy Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Pandas & NumPy Academy 课程共包含 4 节课。

无需下载文件即可读取数据

将数据加载到 Pandas 之前,您不必总是先将文件保存到磁盘。pd.read_csv(url) 可以直接接受 HTTP 或 HTTPS URL,并在一步之内将文件下载到 DataFrame 中。这非常适合读取托管在 GitHub、data.gov 或任意 Web 服务器上的公共数据集,还能让笔记本具备可复现性——任何人都可以运行它们,而无需预先下载资源。

import pandas as pd

url = 'https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv'
df = pd.read_csv(url)
print(df.shape)   # (244, 7)
print(df.head(2))

URL 读取的内部工作原理

将 URL 传递给 read_csv() 时,Pandas 会在内部使用 Python 的 urllib 或 requests 库下载原始字节,然后按照与本地文件完全相同的方式解析它们。大多数读取函数(read_excel、read_json、read_parquet)都支持 URL。使用 .gz 或 .bz2 压缩的文件会自动解压。

import pandas as pd

# Compressed CSV from URL -- auto-decompressed
url = 'https://example.com/data.csv.gz'
df = pd.read_csv(url, compression='infer')
print(df.shape)

为身份验证添加请求标头

某些 API 要求提供身份验证标头(Bearer 令牌、API 密钥)。Pandas 的 URL 读取功能不直接支持自定义标头。在这种情况下,请使用 requests 先下载内容,然后将其包装在 io.StringIO 中,再传递给 Pandas。这种两步模式将 HTTP 处理与数据解析分离开来。

import pandas as pd
import requests
import io

headers = {'Authorization': 'Bearer mytoken123'}
response = requests.get('https://api.example.com/export.csv',
                        headers=headers)
df = pd.read_csv(io.StringIO(response.text))
print(df.shape)

什么是 io.StringIO?

io.StringIO 是 Python 标准库中的一个类,可以根据字符串创建内存中的类文件对象。由于 Pandas 的读取函数需要文件路径或类文件对象,因此您可以将任意 CSV 字符串包装在 StringIO 中,然后直接传入。它对于测试、处理 API 响应,以及解析由 Python 代码动态生成的 CSV 数据都非常有用。

import pandas as pd
import io

csv_text = 'name,score\nAlice,90\nBob,75\nCarol,88'
df = pd.read_csv(io.StringIO(csv_text))
print(df)
#     name  score
# 0  Alice     90
# 1    Bob     75
# 2  Carol     88

用于二进制数据的 io.BytesIO

对于 Excel、Parquet 或压缩 CSV 等二进制格式,请使用 io.BytesIO(基于字节的内存缓冲区),而不是 io.StringIO。将网络响应中的原始字节或数据库 BLOB 字段包装在 BytesIO 中,然后传递给相应的读取器。这样可以避免将临时文件写入磁盘。

import pandas as pd
import requests
import io

# Download an Excel file without saving to disk
response = requests.get('https://example.com/report.xlsx')
buffer = io.BytesIO(response.content)
df = pd.read_excel(buffer, sheet_name='Data')
print(df.shape)

使用 StringIO 进行测试

StringIO 的一个重要用途是在单元测试中:将较小的 CSV 字符串直接嵌入测试函数,而不是提供测试夹具文件。这样可以使测试自包含、可移植且运行迅速。测试数据会与代码一起进行版本控制,不会与外部文件逐渐产生不一致。

import pandas as pd
import io

def test_clean_names():
    raw = 'name,age\n Alice ,30\nBob ,25'
    df = pd.read_csv(io.StringIO(raw))
    df['name'] = df['name'].str.strip()
    assert df['name'].tolist() == ['Alice', 'Bob']
    print('Test passed')

test_clean_names()

写入 StringIO 以生成内存中的 CSV

您可以使用 df.to_csv(buffer) 将 DataFrame 写入 StringIO 缓冲区,从而在内存中生成 CSV 字符串,而无需创建文件。调用 buffer.getvalue() 获取该字符串。这对于将 CSV 嵌入电子邮件正文、在 HTTP 响应中发送 CSV,或在测试中比较预期与实际的 CSV 输出非常有用。

import pandas as pd
import io

df = pd.DataFrame({'x': [1, 2], 'y': [3, 4]})
buffer = io.StringIO()
df.to_csv(buffer, index=False)
csv_string = buffer.getvalue()
print(repr(csv_string))
# 'x,y\n1,3\n2,4\n'

使用 Requests-Cache 缓存远程数据

在开发期间反复下载同一个 URL 速度很慢,还会浪费带宽。请使用 requests-cache,或将第一次下载的内容保存到本地文件。常见做法是检查本地缓存文件是否存在,仅在文件不存在时才回退到 URL。这样既能加快开发速度,又能让笔记本从头开始运行。

import pandas as pd
import os

LOCAL = 'data/tips_cache.csv'
URL = 'https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv'

if os.path.exists(LOCAL):
    df = pd.read_csv(LOCAL)
else:
    df = pd.read_csv(URL)
    df.to_csv(LOCAL, index=False)
print('Loaded:', df.shape)

流式读取大型远程文件

对于超出内存容量的大型远程 CSV 文件,可以将 requests 的流式传输与 chunksize 结合使用。将响应内容逐行流式写入 StringIO 缓冲区,读取数据块并逐步处理。或者,使用 requests 将内容分块直接下载到本地文件,然后在本地副本上使用 Pandas 的分块读取功能。

import requests
import io
import pandas as pd

def stream_csv(url, chunksize=10000):
    with requests.get(url, stream=True) as r:
        content = r.content.decode('utf-8')
    for chunk in pd.read_csv(io.StringIO(content), chunksize=chunksize):
        yield chunk

并行读取多个 URL

当您需要合并来自多个 URL 的数据集时,按顺序读取会很慢。请使用 Python 的 concurrent.futures.ThreadPoolExecutor 并发下载和解析多个 URL,然后使用 pd.concat() 合并结果。对于许多大型文件的受 CPU 限制的解析任务,ProcessPoolExecutor 可能更快。

import pandas as pd
from concurrent.futures import ThreadPoolExecutor

urls = [
    'https://example.com/data_jan.csv',
    'https://example.com/data_feb.csv',
]

with ThreadPoolExecutor(max_workers=4) as ex:
    dfs = list(ex.map(pd.read_csv, urls))
combined = pd.concat(dfs, ignore_index=True)
print(combined.shape)

远程 URL 的安全注意事项

从不受信任的 URL 读取数据存在风险:恶意服务器可能将请求重定向到意外格式,提供大到耗尽内存的文件,或注入会干扰解析器的内容。请始终验证 URL 方案(处理敏感数据时必须使用 HTTPS),为下载设置超时时间,并在首次探索不熟悉的 URL 时使用 nrows= 限制行数。

import pandas as pd
import requests
import io

url = 'https://trusted-source.example.com/data.csv'
response = requests.get(url, timeout=30)  # 30-second timeout
response.raise_for_status()              # raise on HTTP error
df = pd.read_csv(io.StringIO(response.text), nrows=1000)
print(df.shape)

快速检查

测试您对本课中从 URL 和 StringIO 读取数据的理解。

课程回顾

在本课中,您学到了:pd.read_csv() 可以直接接受 HTTP/HTTPS URL,无需先下载文件;io.StringIO 可以将 CSV 字符串包装成类文件对象,使 Pandas 能够从内存中解析它;以及io.BytesIO 对 Excel 和 Parquet 等二进制格式也能实现同样的功能。至此,数据读写课程已完成——接下来,我们将使用布尔索引和 query() 方法精确筛选 DataFrame。

免费开始

用 AI 导师学习 Python — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
30
课程
120

常见问题解答

「从 URL 与 StringIO 读取」课时是免费的吗?

是的 — 「从 URL 与 StringIO 读取」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Pandas & NumPy Academy 课程的其余内容,请升级到 CoddyKit PRO。 Pandas & NumPy Academy 课程共包含 4 节课。

「从 URL 与 StringIO 读取」这节课中我会学到什么?

直接从 URL 加载远程 CSV 文件,并使用 io.StringIO 解析内存中的 CSV 字符串以进行测试。 你通过在浏览器中直接运行的动手代码来练习 Pandas & NumPy Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Pandas & NumPy Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Pandas & NumPy Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「从 URL 与 StringIO 读取」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Pandas & NumPy Academy 课中编写并运行代码吗?

能。每节 Pandas & NumPy Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 读取 CSV 文件
  2. 读取 Excel 与 JSON 文件
  3. 将 DataFrames 写入文件
  4. 从 URL 与 StringIO 读取
← 返回 Pandas & NumPy Academy