Как делать вызовы API с помощью Python в 2025 году

Изучите современные методы GET/POST, разберите JSON и используйте SDK для эффективных вызовов API на Python.
8 мин. чтения
How to make API calls using Python blog image

В этом руководстве мы рассмотрим следующие концепции использования API в Python:

  1. Что такое HTTP?
  2. Что такое REST API?
  3. Как сделать GET-запрос
  4. Как сделать POST-запрос
  5. Как использовать SDK

Что такое HTTP?

HTTP (Hypertext Transfer Protocol) – это стандарт для передачи большинства данных через Интернет. Вы, вероятно, слышали, что базы данных составляют бэкэнд большинства веб-сайтов, и это действительно так, но есть нюансы в том, как наш клиент (браузер или Python-скрипт) взаимодействует с базой данных. HTTP – это коммуникационный слой между клиентом и внутренним сервером.

При использовании HTTP для скраппинга и веб-интерфейсов API вы, скорее всего, будете применять именно эти методы.

  • GET: Наиболее часто используемый метод. Когда вы посещаете сайт, ваш браузер выполняет GET для получения HTML, а затем отображает страницу для просмотра.
  • ПОСТ: Это второй по распространенности метод. POST используется для безопасной передачи больших объемов данных – чаще всего для добавления чего-либо в базу данных. Когда вы заполняете формы и опросы или публикуете сообщения в социальных сетях, вы выполняете POST-запрос.
  • PUT: Запросы PUT используются для обновления существующих элементов в базе данных. Когда вы редактируете пост в социальной сети, PUT используется под капотом.
  • DELETE: Если вы хотите удалить пост в социальных сетях (или что-либо еще из базы данных), ваш браузер отправляет серверу запрос DELETE, чтобы удалить его.

HTTP и отсутствие стандартов возврата

При всей своей простоте HTTP не имеет универсального стандарта возврата. Некоторые серверы по умолчанию возвращают HTML, другие – JSON или даже устаревшие структуры данных, такие как XML и обычный текст.

Для начала давайте сделаем базовый GET-запрос. Если у вас еще не установлен Python Requests, вы можете установить его через pip.

pip install requests

Установив Requests, вы можете выполнить следующий код, чтобы сделать простой GET. Обратите внимание на вывод терминала.

import requests

response = requests.get("https://quotes.toscrape.com")

print(response.text)

После выполнения кода вы должны заметить, что у нас получилась HTML-страница. Она отлично подходит для просмотра в браузере, но в терминале она выглядит довольно уродливо. Приведенный ниже вывод был обрезан, но вы поняли, о чем идет речь.

<!DOCTYPE html>
<html lang="en">
<head>
        <meta charset="UTF-8">
        <title>Quotes to Scrape</title>
    <link rel="stylesheet" href="/static/bootstrap.min.css">
    <link rel="stylesheet" href="/static/main.css">


</head>
<body>
    <div class="container">
        <div class="row header-box">
            <div class="col-md-8">
                <h1>
                    <a href="/" style="text-decoration: none">Quotes to Scrape</a>
                </h1>
            </div>
            <div class="col-md-4">
                <p>

                    <a href="/login">Login</a>

                </p>
            </div>
        </div>


<div class="row">
    <div class="col-md-8">

    <div class="quote" itemscope itemtype="http://schema.org/CreativeWork">
        <span class="text" itemprop="text">“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”</span>
        <span>by <small class="author" itemprop="author">Albert Einstein</small>
        <a href="/author/Albert-Einstein">(about)</a>
        </span>
        <div class="tags">
            Tags:
            <meta class="keywords" itemprop="keywords" content="change,deep-thoughts,thinking,world" /    >

            <a class="tag" href="/tag/change/page/1/">change</a>

            <a class="tag" href="/tag/deep-thoughts/page/1/">deep-thoughts</a>

            <a class="tag" href="/tag/thinking/page/1/">thinking</a>

            <a class="tag" href="/tag/world/page/1/">world</a>

        </div>
    </div>

    <div class="quote" itemscope itemtype="http://schema.org/CreativeWork">
        <span class="text" itemprop="text">“It is our choices, Harry, that show what we truly are, far more than our abilities.”</span>
        <span>by <small class="author" itemprop="author">J.K. Rowling</small>
        <a href="/author/J-K-Rowling">(about)</a>
        </span>
        <div class="tags">
            Tags:
            <meta class="keywords" itemprop="keywords" content="abilities,choices" /    >

            <a class="tag" href="/tag/abilities/page/1/">abilities</a>

            <a class="tag" href="/tag/choices/page/1/">choices</a>

        </div>
    </div>

HTML-страницы предназначены для чтения и отображения браузерами. Они не предназначены для чтения или интеграции в ваш код.

Как REST (Representational State Transfer) исправляет ситуацию

API REST дают нам стандарт проектирования конвейеров данных. JSON – самый популярный тип возврата в REST API. Он гибкий и легко читаемый. Этот понятный и читаемый синтаксис также облегчает его разбор из вашей среды программирования.

Посмотрите ниже, как на самом деле выглядит JSON. Помните, что для получения такой структуры данных мы используем REST API.

{
    "name": "Jake",
    "age": 34,
    "professions": ["writing", "coding"]
}

API REST используют конечные точки, параметры и методы HTTP для управления возвращаемыми данными и их форматом.

Выполнение первого запроса API

Теперь, когда вы знаете, что должен делать REST API, давайте попробуем использовать его на практике. Quotes to Scrape также имеет REST API. Вместо того чтобы просто получать данные с главной страницы, теперь мы обратимся к их API. Мы взаимодействуем с сервером через конечные точки.

Наш полный конечный пункт /api/quotes можно разбить на две части.

  1. /api: Это говорит серверу, что нам нужны структурированные данные API, а не HTML-страницы.
  2. /quotes: Мы хотим, чтобы API возвращал данные из конечной точки quotes.

Оформление заявки

Запустите код, как это было раньше.

import requests
import json

response = requests.get("https://quotes.toscrape.com/api/quotes")

print(json.dumps(response.json(), indent=4))

Теперь наши данные возвращаются чистыми и структурированными. Их легко разобрать, и теперь мы можем делать с ними практически все, что угодно.

{
    "has_next": true,
    "page": 1,
    "quotes": [
        {
            "author": {
                "goodreads_link": "/author/show/9810.Albert_Einstein",
                "name": "Albert Einstein",
                "slug": "Albert-Einstein"
            },
            "tags": [
                "change",
                "deep-thoughts",
                "thinking",
                "world"
            ],
            "text": "\u201cThe world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.\u201d"    
        },
        {
            "author": {
                "goodreads_link": "/author/show/1077326.J_K_Rowling",
                "name": "J.K. Rowling",
                "slug": "J-K-Rowling"
            },
            "tags": [
                "abilities",
                "choices"
            ],
            "text": "\u201cIt is our choices, Harry, that show what we truly are, far more than our abilities.\u201d"
        },
        {
            "author": {
                "goodreads_link": "/author/show/9810.Albert_Einstein",
                "name": "Albert Einstein",
                "slug": "Albert-Einstein"
            },
            "tags": [
                "inspirational",
                "life",
                "live",
                "miracle",
                "miracles"
            ],
            "text": "\u201cThere are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.\u201d"
        },
        {
            "author": {
                "goodreads_link": "/author/show/1265.Jane_Austen",
                "name": "Jane Austen",
                "slug": "Jane-Austen"
            },
            "tags": [
                "aliteracy",
                "books",
                "classic",
                "humor"
            ],
            "text": "\u201cThe person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.\u201d"
        },
        {
            "author": {
                "goodreads_link": "/author/show/82952.Marilyn_Monroe",
                "name": "Marilyn Monroe",
                "slug": "Marilyn-Monroe"
            },
            "tags": [
                "be-yourself",
                "inspirational"
            ],
            "text": "\u201cImperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.\u201d"        
        },
        {
            "author": {
                "goodreads_link": "/author/show/9810.Albert_Einstein",
                "name": "Albert Einstein",
                "slug": "Albert-Einstein"
            },
            "tags": [
                "adulthood",
                "success",
                "value"
            ],
            "text": "\u201cTry not to become a man of success. Rather become a man of value.\u201d"
        },
        {
            "author": {
                "goodreads_link": "/author/show/7617.Andr_Gide",
                "name": "Andr\u00e9 Gide",
                "slug": "Andre-Gide"
            },
            "tags": [
                "life",
                "love"
            ],
            "text": "\u201cIt is better to be hated for what you are than to be loved for what you are not.\u201d"
        },
        {
            "author": {
                "goodreads_link": "/author/show/3091287.Thomas_A_Edison",
                "name": "Thomas A. Edison",
                "slug": "Thomas-A-Edison"
            },
            "tags": [
                "edison",
                "failure",
                "inspirational",
                "paraphrased"
            ],
            "text": "\u201cI have not failed. I've just found 10,000 ways that won't work.\u201d"
        },
        {
            "author": {
                "goodreads_link": "/author/show/44566.Eleanor_Roosevelt",
                "name": "Eleanor Roosevelt",
                "slug": "Eleanor-Roosevelt"
            },
            "tags": [
                "misattributed-eleanor-roosevelt"
            ],
            "text": "\u201cA woman is like a tea bag; you never know how strong it is until it's in hot water.\u201d"
        },
        {
            "author": {
                "goodreads_link": "/author/show/7103.Steve_Martin",
                "name": "Steve Martin",
                "slug": "Steve-Martin"
            },
            "tags": [
                "humor",
                "obvious",
                "simile"
            ],
            "text": "\u201cA day without sunshine is like, you know, night.\u201d"
        }
    ],
    "tag": null,
    "top_ten_tags": [
        [
            "love",
            14
        ],
        [
            "inspirational",
            13
        ],
        [
            "life",
            13
        ],
        [
            "humor",
            12
        ],
        [
            "books",
            11
        ],
        [
            "reading",
            7
        ],
        [
            "friendship",
            5
        ],
        [
            "friends",
            4
        ],
        [
            "truth",
            4
        ],
        [
            "simile",
            3
        ]
    ]
}

Выполнение аутентифицированного запроса

Теперь, когда мы рассмотрели, как запрашивать общедоступные данные, давайте посмотрим на аутентифицированные API. Во многих случаях для получения данных вам понадобится ключ API. Большинство серверов API требуют заголовок Authorization с вашим ключом API для аутентификации запроса.

Выполнить базовый GET-запрос довольно просто. Теперь попробуем сделать POST-запрос. POST-запросы используются для безопасной обработки больших объемов информации. В приведенном ниже коде мы используем API Web Unlocker, чтобы разобрать страницу и вернуть разметку.

import requests

API_KEY = "your-api-key"
ZONE = "web_unlocker1"

url = "https://api.brightdata.com/request"
headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}
payload = {
    "url": "https://quotes.toscrape.com/",
    "zone": ZONE,
    "format": "raw",
    "data_format": "markdown"
}

response = requests.post(url, headers=headers, json=payload)

print(response.text)

На этот раз наш запрос отправляется на https://api.brightdata.com/request. Все контролируется нашими заголовками и полезной нагрузкой.

Вот наши заголовки:

  • "Авторизация": f "Bearer {API_KEY}": Это связывает запрос с вашей учетной записью Bright Data.
  • "Content-Type": "application/json": Это говорит серверу, что мы отправляем данные в формате JSON.

Теперь взгляните на полезную нагрузку:

  • "url": url, к которому мы хотим получить доступ с помощью Web Unlocker.
  • "zone": Имя зоны, которое вы присвоили своему экземпляру Web Unlocker.
  • "format": Формат ответа, который мы хотим получить (в данном случае raw).
  • "data_format": Мы используем “markdown” – это говорит Bright Data, что мы хотим, чтобы страница была разобрана в формате markdown. Он не такой гибкий, как JSON, но его можно легко преобразовать в JSON.

Вот вывод терминала, когда страница преобразована в markdown.

# [Quotes to Scrape](/) 

[Login](/login)

“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.” by Albert Einstein [(about)](/author/Albert-Einstein)

 Tags: [change](/tag/change/page/1/) [deep-thoughts](/tag/deep-thoughts/page/1/) [thinking](/tag/thinking/page/1/) [world](/tag/world/page/1/)

“It is our choices, Harry, that show what we truly are, far more than our abilities.” by J.K. Rowling [(about)](/author/J-K-Rowling)

 Tags: [abilities](/tag/abilities/page/1/) [choices](/tag/choices/page/1/)

“There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.” by Albert Einstein [(about)](/author/Albert-Einstein)

 Tags: [inspirational](/tag/inspirational/page/1/) [life](/tag/life/page/1/) [live](/tag/live/page/1/) [miracle](/tag/miracle/page/1/) [miracles](/tag/miracles/page/1/)

“The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.” by Jane Austen [(about)](/author/Jane-Austen) 

 Tags: [aliteracy](/tag/aliteracy/page/1/) [books](/tag/books/page/1/) [classic](/tag/classic/page/1/) [humor](/tag/humor/page/1/)

“Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.” by Marilyn Monroe [(about)](/author/Marilyn-Monroe)

 Tags: [be-yourself](/tag/be-yourself/page/1/) [inspirational](/tag/inspirational/page/1/)

“Try not to become a man of success. Rather become a man of value.” by Albert Einstein [(about)](/author/Albert-Einstein)

 Tags: [adulthood](/tag/adulthood/page/1/) [success](/tag/success/page/1/) [value](/tag/value/page/1/)

“It is better to be hated for what you are than to be loved for what you are not.” by André Gide [(about)](/author/Andre-Gide)

 Tags: [life](/tag/life/page/1/) [love](/tag/love/page/1/)

“I have not failed. I've just found 10,000 ways that won't work.” by Thomas A. Edison [(about)](/author/Thomas-A-Edison)

 Tags: [edison](/tag/edison/page/1/) [failure](/tag/failure/page/1/) [inspirational](/tag/inspirational/page/1/) [paraphrased](/tag/paraphrased/page/1/)

“A woman is like a tea bag; you never know how strong it is until it's in hot water.” by Eleanor Roosevelt [(about)](/author/Eleanor-Roosevelt)        

 Tags: [misattributed-eleanor-roosevelt](/tag/misattributed-eleanor-roosevelt/page/1/)

“A day without sunshine is like, you know, night.” by Steve Martin [(about)](/author/Steve-Martin)

 Tags: [humor](/tag/humor/page/1/) [obvious](/tag/obvious/page/1/) [simile](/tag/simile/page/1/)

* [Next →](/page/2/)

## Top Ten tags

[love](/tag/love/) [inspirational](/tag/inspirational/) [life](/tag/life/) [humor](/tag/humor/) [books](/tag/books/) [reading](/tag/reading/) [friendship](/tag/friendship/) [friends](/tag/friends/) [truth](/tag/truth/) [simile](/tag/simile/)

 Quotes by: [GoodReads.com](https://www.goodreads.com/quotes)

 M

Для аутентификации используется уникальный идентификатор – как правило, ключ API. В данном случае мы получили доступ к Web Unlocker, но принцип тот же – независимо от того, какой API-сервис вы используете.

Обработка ответа

Каждый ответ содержит код состояния. Коды состояния используются для передачи различных сообщений обратно клиенту. В идеальном мире вы всегда будете получать статус 200.

К сожалению, мир не идеален. Если вы получили код не-200, это означает, что что-то не так.

  • 400-499: Эти коды обычно означают ошибку на стороне клиента. Дважды проверьте свой ключ API и формат запроса.
  • 500-599: Этот диапазон указывает на ошибку сервера. Ваш запрос был в порядке, но сервер не смог его выполнить по той или иной причине.

Подробнее о кодах состояния вы можете узнать здесь. Если вы хотите узнать, как обрабатывать эти коды состояния в Python, посмотрите это руководство по логике повторных попыток.

Пропуск шаблонов с помощью SDK

SDK (комплект для разработки программного обеспечения) позволяет нам подключаться к REST API без необходимости писать шаблоны для обработки ошибок и логики повторных попыток. API OpenAI также предлагает полный REST API. Вы можете взглянуть на него здесь.

Чтобы установить их SDK и пропустить HTTP-запросы, выполните следующую команду.

pip install openai

Теперь мы импортируем OpenAI SDK. Мы получаем обычную HTML-страницу, как и в первом случае. Если вам интересно разбирать HTML вручную, вы можете узнать , как использовать Requests с помощью BeautifulSoup. Получив HTML-страницу, мы используем SDK, чтобы передать ее в ChatGPT для разбора.

from openai import OpenAI
import requests

OPENAI_API_KEY = "sk-your-openai-api-key"

response = requests.get("https://quotes.toscrape.com")
html_page = response.text

client = OpenAI(api_key=OPENAI_API_KEY)

chat = client.chat.completions.create(
    messages=[
        {
            "role": "user",
            "content": f"Parse the quotes from the following page. I want JSON only--zero commentary from you, here's the page: {html_page}",
        }
    ],
    model="gpt-4o-mini",
)

reply = chat.choices[0].message.content
print(f"ChatGPT: {reply}")

На этот раз посмотрите на результат. Никакого парсинга не требуется – только данные внутри json-блока.

[
    {
        "text": "The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.",
        "author": "Albert Einstein",
        "tags": ["change", "deep-thoughts", "thinking", "world"]
    },
    {
        "text": "It is our choices, Harry, that show what we truly are, far more than our abilities.",
        "author": "J.K. Rowling",
        "tags": ["abilities", "choices"]
    },
    {
        "text": "There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.",   
        "author": "Albert Einstein",
        "tags": ["inspirational", "life", "live", "miracle", "miracles"]
    },
    {
        "text": "The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.",
        "author": "Jane Austen",
        "tags": ["aliteracy", "books", "classic", "humor"]
    },
    {
        "text": "Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.",
        "author": "Marilyn Monroe",
        "tags": ["be-yourself", "inspirational"]
    },
    {
        "text": "Try not to become a man of success. Rather become a man of value.",
        "author": "Albert Einstein",
        "tags": ["adulthood", "success", "value"]
    },
    {
        "text": "It is better to be hated for what you are than to be loved for what you are not.",
        "author": "André Gide",
        "tags": ["life", "love"]
    },
    {
        "text": "I have not failed. I've just found 10,000 ways that won't work.",
        "author": "Thomas A. Edison",
        "tags": ["edison", "failure", "inspirational", "paraphrased"]
    },
    {
        "text": "A woman is like a tea bag; you never know how strong it is until it's in hot water.",
        "author": "Eleanor Roosevelt",
        "tags": ["misattributed-eleanor-roosevelt"]
    },
    {
        "text": "A day without sunshine is like, you know, night.",
        "author": "Steve Martin",
        "tags": ["humor", "obvious", "simile"]
    }
]

SDK дают вам всю мощь REST API без необходимости ручного управления HTTP. Если вам интересно узнать, как скреативить с помощью искусственного интеллекта, посмотрите наши руководства для Claude и DeepSeek.

Заключение

Теперь, когда вы знаете, как делать базовые запросы к API с помощью Python, вы можете перейти к более серьезным проектам. Вы можете использовать API для взаимодействия с различными сервисами для получения данных и даже использовать SDK для автоматического анализа этих данных. В этом учебнике мы использовали Web Unlocker, но Bright Data предлагает множество других продуктов, которые помогут вам в работе с данными.

  • Резидентные прокси: Направляйте свой HTTP-трафик через реальные устройства с IP-адресами жилых домов.
  • API скрепера: Полностью автоматизируйте свой поиск и загружайте результаты прямо в свою среду программирования.
  • Браузер для скрапинга: Обходите CAPTCHA и управляйте настоящим безголовым браузером прямо внутри вашего Python-скрипта.

Запишитесь на бесплатную пробную версию и начните работу уже сегодня!

Кредитная карта не требуется