请求csv.gz文件遇403错误及如何直接转pandas DataFrame?
问题解决方案
一、403状态码排查方案
403是HTTP权限类状态码,和你要下载的.gz文件格式完全无关,服务器在返回文件内容之前就已经拒绝了你的请求,排查方向如下:
- 首先确认S3预签名URL参数有效性:你使用的
AWSAccessKeyId、Signature、Expires是AWS S3预签名URL的标准参数,403大概率是参数失效导致:- 检查
Expires参数值是否已过期,预签名URL的有效期过了之后就会直接返回403 - 确认
Signature签名是否正确,签名计算错误、或者请求参数和签名不匹配都会触发403 - 确认
AWSAccessKeyId对应的身份有该S3对象的访问权限
- 检查
- 其次可以添加请求头模拟浏览器访问,部分站点会拦截无UA标识的爬虫请求,给
requests.get补充headers参数即可,示例:
headers = { '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' } response = requests.get(url, params=query, headers=headers)
二、200响应转pandas DataFrame的方法
无需下载到本地,直接用BytesIO处理响应的二进制内容即可,pandas原生支持gzip压缩格式的数据流读取,完整示例代码如下:
import pandas as pd import requests from io import BytesIO # 替换为你的有效请求参数 query = {'AWSAccessKeyId':'theaccesskey', 'Signature':'thesignature','Expires':'12345'} url = 'https://s3.amazonaws.com/research.insideairbnb.com/data/united-states/or/portland/2015-12-02/data/listings.csv.gz' headers = { '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' } response = requests.get(url, params=query, headers=headers) if response.status_code == 200: # 直接读取二进制流,compression参数可省略,pandas会自动识别gzip格式 df = pd.read_csv(BytesIO(response.content), compression='gzip') # 后续可正常操作DataFrame print(df.head())
内容的提问来源于stack exchange,提问作者Margot Black
相关产品推荐
相关产品推荐

