Python中DDG图片搜索返回生成器函数报错:客户端已关闭
DDG API生成器封装后调用报错的解决方法
在学习fast.ai课程时,使用Python结合DuckDuckGo API(DDG API)下载图片时遇到以下问题:
- 在
with DDGS()代码块内直接操作生成器,能正常获取图片URL; - 将搜索逻辑封装成函数并返回生成器后,调用
next()触发RuntimeError,错误提示:RuntimeError: 无法发送请求,因为客户端已关闭。
可正常运行的代码:
with DDGS() as ddgs: keywords = 'dolphin' ddgs_images_gen = ddgs.images( keywords, region="wt-wt", safesearch="moderate", type_image="photo", ) dolphin = next(ddgs_images_gen) print(dolphin['image'])
报错的函数及调用代码:
def search_ddg(search_terms): with DDGS() as ddgs: keywords = search_terms, # 注意此处多了逗号,导致keywords是元组 ddgs_images_gen = ddgs.images( keywords, region="wt-wt", safesearch="moderate", type_image="photo", ) return ddgs_images_gen dolphins = search_ddg('dolphin') next(dolphins) # 此处报错
问题原因
生成器是惰性求值的:ddgs.images()返回的生成器不会立即执行API请求,只有当调用next()或迭代它时,才会真正和DDGS客户端交互。
但在报错代码中,with块在生成器返回后就执行完毕,DDGS客户端被自动关闭。后续调用next()时,生成器尝试使用已关闭的客户端,因此触发RuntimeError。
另外注意:原代码中keywords = search_terms,多了一个逗号,导致keywords变成了元组,可能会干扰搜索逻辑,需要去掉这个逗号。
解决方案
方案1:使用生成器函数封装(推荐)
将函数改为生成器函数,利用yield from转发生成器的结果,这样with块会保持DDGS客户端打开,直到生成器迭代完成:
def search_ddg(search_terms): with DDGS() as ddgs: ddgs_images_gen = ddgs.images( search_terms, region="wt-wt", safesearch="moderate", type_image="photo", ) yield from ddgs_images_gen # 调用示例 dolphins = search_ddg('dolphin') next(dolphins) # 正常执行
方案2:在函数内转换为列表返回
如果不需要惰性求值,可以在with块内将生成器转换为列表,提前完成所有API请求,返回结果列表:
def search_ddg(search_terms): with DDGS() as ddgs: ddgs_images_gen = ddgs.images( search_terms, region="wt-wt", safesearch="moderate", type_image="photo", ) return list(ddgs_images_gen) # 调用示例 dolphins = search_ddg('dolphin') print(dolphins[0]['image']) # 正常执行
内容的提问来源于stack exchange,提问作者triplej
相关产品推荐
相关产品推荐

