Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用会话()在python中使用API和请求加速获取图像的方法?_Python_Api_Python Requests - Fatal编程技术网

使用会话()在python中使用API和请求加速获取图像的方法?

使用会话()在python中使用API和请求加速获取图像的方法?,python,api,python-requests,Python,Api,Python Requests,我试图通过一个API检索10个图像,该API首先向API发出请求,然后将返回的JSON数据中的10个图像URL存储在一个列表中,从而返回JSON数据。在我最初的迭代中,我对这些URL发出了单独的请求,并将响应内容保存到文件中。下面给出了我的代码,由于明显的原因,删除了我的API密钥: def get_image(search_term): number_images = 10 images = requests.get("https://pixabay.com/api/?key

我试图通过一个API检索10个图像,该API首先向API发出请求,然后将返回的JSON数据中的10个图像URL存储在一个列表中,从而返回JSON数据。在我最初的迭代中,我对这些URL发出了单独的请求,并将响应内容保存到文件中。下面给出了我的代码,由于明显的原因,删除了我的API密钥:

def get_image(search_term):

    number_images = 10
    images = requests.get("https://pixabay.com/api/?key=insertkey&q={}&per_page={}".format(search_term,number_images))
    images_json_dict = images.json()

    hits = images_json_dict["hits"]
    urls = []
    for i in range(len(hits)):
        urls.append(hits[i]["webformatURL"])

    count =0
    for url in urls:
        picture_request = requests.get(url)
        if picture_request.status_code == 200:
            try:
                with open(dir_path+r'\\images\\{}.jpg'.format(count),'wb') as f:
                    f.write(picture_request.content)
            except:
                    os.mkdir(dir_path+r'\\images\\')
                    with open(dir_path+r'\\images\\{}.jpg'.format(count),'wb') as f:
                        f.write(picture_request.content)
        count+=1
除了速度非常慢之外,它工作得很好。可能需要7秒钟才能将这10幅图像拉入并保存到一个文件夹中。我了解到可以使用请求库中的Sessions()来提高性能-我希望尽快获得这些图像。我修改了如下所示的代码,但是我遇到的问题是,sessions对象上的get请求返回requests.sessions.Session对象,而不是响应代码,并且没有.content方法来检索内容(我在下面的相关代码行中添加了注释)。我对编程比较陌生,所以我不确定这是否是最好的方法。我的问题是,现在我正在使用Session()如何使用sessions检索图像内容,或者是否有更聪明的方法来实现这一点

def get_image(search_term):

    number_images = 10
    images = requests.get("https://pixabay.com/api/?key=insertkey&q={}&per_page={}".format(search_term,number_images))
    images_json_dict = images.json()

    hits = images_json_dict["hits"]
    urls = []
    for i in range(len(hits)):
        urls.append(hits[i]["webformatURL"])

    count =0
    #Now using Session()
    picture_request = requests.Session()
    for url in urls:
        picture_request.get(url)
        #This will no longer work as picture_request is an object
        if picture_request == 200:
            try:
                with open(dir_path+r'\\images\\{}.jpg'.format(count),'wb') as f:
                    #This will no longer work as there is no .content method
                    f.write(picture_request.content)
            except:
                    os.mkdir(dir_path+r'\\images\\')
                    with open(dir_path+r'\\images\\{}.jpg'.format(count),'wb') as f:
                        #This will no longer work as there is no .content method
                        f.write(picture_request.content)
        count+=1

假设您希望坚持使用
请求
库,那么您将需要使用
线程
来创建多个并行实例

concurrent.futures
具有方便的构造函数,可使用concurrent.futures.ThreadPoolExecutor创建多个线程

fetch()
用于下载图像。
fetch_all()
用于创建线程池,您可以通过传递
threads
参数来选择要运行的线程数。
get_url()
是检索URL列表的函数。您应该传递您的
令牌
(键)和
搜索词

注意:如果Python版本早于3.7,则应将f字符串(
f“{args}”
)替换为常规格式函数(
“{}.format(args)

导入操作系统
导入请求
从同步进口期货
def fetch(url,会话=无):
如果会议:
r=session.get(url,超时=60。)
其他:
r=requests.get(url,超时=60。)
r、 为_状态()提出_
返回r.content
def fetch_all(URL,session=requests.session(),threads=8):
使用futures.ThreadPoolExecutor(max_workers=threads)作为执行器:
future_to_url={executor.submit(fetch,url,session=session):url中url的url}
用于期货中的期货。完成时(期货到期货url):
url=未来到未来url[未来]
如果future.exception()为无:
产生url,future.result()
其他:
打印(f“{url}生成异常:{future.exception()}”)
产生url,无
def get_URL(搜索词,数字图像=10,标记=”,会话=requests.session()):
r=请求。获取(f)https://pixabay.com/api/?key={token}&q={search\u term}&per\u page={number\u images}”)
r、 为_状态()提出_
URL=[hit[“webformatURL”]表示r.json()中的hit。get(“hits”,[])]
返回URL
如果名称=“\uuuuu main\uuuuuuuu”:
root_dir=os.getcwd()
会话=请求。会话()
URL=获取URL(“术语”,token=“token”,session=session)
对于url,fetch_all中的内容(url,会话=会话):
如果内容不是无:
f_dir=os.path.join(根目录,“图像”)
如果不是os.path.isdir(f_dir):
os.makedirs(f_dir)
将open(os.path.join(f_dir,os.path.basename(url)),“wb”)作为f:
f、 写作(内容)

我也建议你看看。这里我不提供示例,但为类似的任务提供了示例,您可以在这里了解更多信息。

您可以使用会话,但实际上并不能提高性能。您需要的是并行下载图像,为此,您可以使用或
线程
库来运行多个实例,或者使用
异步请求代替
请求
使用
aiohttp
。如果你真的需要的话,第二个会有更好的性能。我可以写一些你喜欢的例子。@XCanG这会很有帮助的,谢谢。我已经阅读了一些关于线程的教程,但我不知道它是如何工作的,也不知道如何在这种特殊情况下应用它。所以你想将
线程
用于
请求