使用requests的stream=True从Amazon S3流式获取Common Crawl数据报错求助
解决Common Crawl流式抓取与warcio配合的问题
我之前也踩过类似的坑,Common Crawl的S3存储在流式请求时确实需要注意不少细节,尤其是内存有限没法下载完整文件的场景。下面给你两个靠谱的解决方案,都能实现内存友好的流式处理:
方法一:使用requests + warcio流式迭代器
requests的stream=True本身支持流式响应,但要正确配合warcio的ArchiveIterator,还要注意S3对请求头的要求——默认的requests User-Agent很可能会被拦截,得自定义一个。
完整代码示例:
import requests from warcio.archiveiterator import ArchiveIterator def stream_cc_records(cc_url): # 自定义浏览器样式的User-Agent,避免被S3拦截 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' } # 用with语句管理请求,确保连接自动关闭 with requests.get(cc_url, stream=True, headers=headers, timeout=30) as resp: # 先检查响应状态,403/404之类的错误要及时处理 resp.raise_for_status() # 直接把原始字节流传给ArchiveIterator,stream=True开启逐块解析 for record in ArchiveIterator(resp.raw, stream=True): # 只处理响应记录(跳过请求记录、元数据记录等) if record.rec_type == 'response': # 按需读取当前记录的内容,不要一次性缓存太多数据 content = record.content_stream().read() # 这里替换成你的业务逻辑,比如解析HTML、提取目标字段等 print(f"处理一条响应,内容大小:{len(content)} bytes") # 替换成你的Common Crawl目标URL target_url = "https://commoncrawl.s3.amazonaws.com/crawl-data/CC-MAIN-2018-05/segments/..." stream_cc_records(target_url)
关键细节:
- 必须用
with语句管理requests响应对象,防止连接泄漏 resp.raw是原始字节流对象,直接传给ArchiveIterator即可,无需额外转换ArchiveIterator的stream=True参数会让它逐块解析WARC文件,不会把整个文件加载到内存
方法二:使用boto3直接流式读取S3对象
如果能使用AWS官方SDK(boto3),这种方法会更稳定——boto3会自动处理S3的签名、重试、断点续传等细节,比requests更适配S3场景。
代码示例:
import boto3 from warcio.archiveiterator import ArchiveIterator def stream_cc_via_boto3(bucket_name, s3_key): # 初始化S3客户端(Common Crawl存储是公开可读的,不需要密钥) s3 = boto3.client('s3', config=boto3.client.Config(retries={'max_attempts': 5})) # 发起流式获取请求,返回的Body是可迭代的字节流 with s3.get_object(Bucket=bucket_name, Key=s3_key) as s3_resp: # 用ArchiveIterator处理流式内容 for record in ArchiveIterator(s3_resp['Body'], stream=True): if record.rec_type == 'response': content = record.content_stream().read() print(f"处理一条响应,内容大小:{len(content)} bytes") # Common Crawl的固定bucket是commoncrawl,s3_key是URL中域名后的路径部分 stream_cc_via_boto3( bucket_name='commoncrawl', s3_key='crawl-data/CC-MAIN-2018-05/segments/...' )
优势:
- 自动处理临时连接中断等异常,重试机制更完善
- 不需要手动构造请求头,减少被拦截的概率
常见问题排查
- 403 Forbidden错误:大概率是User-Agent的问题,换一个浏览器样式的UA就能解决(方法一中已经配置)
- 内存仍飙升:检查你的业务逻辑,是不是把所有记录的内容都存在了列表/全局变量里?要及时释放不再使用的内存
- 连接超时:给requests添加
timeout参数,或者给boto3客户端配置重试次数(如方法二中的retries={'max_attempts': 5})
内容的提问来源于stack exchange,提问作者Superman
相关产品推荐
相关产品推荐

