Как найти api для сайта

Время на прочтение
4 мин

Количество просмотров 15K

Поиск открытого API сайта или Ускоряем парсинг в 10 раз

image

Цель статьи — описать алгоритм действий поиска открытого API сайта.
Целевая аудитория статьи — программисты, которым интересен парсинг и анализ уязвимостей сайтов.

В статье рассмотрим пример поиска API сайта edadeal.ru, познакомимся с протоколом google protobuf и сравним скорость различных подходов парсинга

1. Введение

Парсинг (в контексте статьи) — это автоматизированный процесс извлечение данных из Интернета.

Существует 2 подхода к извлечению данных со страниц сайта

  1. Извлекать данные из HTML-кода страницы сайта
    Плюсы — этот способ прост и работает всегда, так как код страницы всегда доступен пользователю
    Минусы — этот способ может работать долго (несколько секунд), если часть данных генерирует java script (например, данные появляются только после прокручивания страницы или нажатия кнопки)

  2. Использовать API сайта
    Плюсы — быстрее первого способа и не зависит от изменений структуры html-страницы
    Минус — не у всех сайтов есть открытое API

В статье рассмотрим пример поиска API сайта edadeal.ru, познакомимся с протоколом google protobuf и сравним скорость двух подходов парсинга

2. Постановка задачи

Задача — извлечь данные о продуктах с сайта Едадил (название продукта, цена, размер скидки, магазин, город и т.д)

3. Решение

1 Делаем запрос к странице, которую мы хотим парсить.
2 Перебираем все запросы, которые делает сайт. Для этого используем DevTools браузера
image

3 Анализируем запросы
Из названия запроса понимаем, что нам нужен запрос
https://squark.edadeal.ru/web/search/offers?count=30&locality=moskva&page=1&retailer=5ka

В ответ на запрос получаем файл (назовем его binary_file.bin). Как узнать кодировку этого файла?
Формат файла из пункта 3 нам подсказывает строка-хедер content-type: application/x-protobuf

4 Определим структуру данных (.proto файл)
с помощью утилиты protoc (http://google.github.io/proto-lens/installing-protoc.html) преобразуем закодированный файл в понятный человеку формат
protoc --decode_raw < binary_file.bin

Получаем список словарей:

1 {
  1: "e341_26007177W202222O32631623332600A"
  2: "320242321203320260320273320265321202320275320260321217 320261321203320274320260320263320260 Familia Plus, 2 321201320273320276321217, 12 321200321203320273320276320275320276320262, 1 321203320277."
  3: "https://leonardo.edadeal.io/dyn/cr/catalyst/offers/u4nf6zbkjc3m5lss46ucvxjafm.jpg"
  4: 0x43ad7eb8
  5: 0x4347e666
  7: ";5332^c2121346204237RT002026610"
  8: 0x41400000
  9: "321210321202"
  10: 0x422c0000
  11: "%"
  13: 43
  15: "2022-07-26T00:00:00Z"
  16: "2022-08-01T00:00:00Z"
  19: "A105L332nPg230342q3753133514336"
  20 {
    1: 0x3f800000
    2: 0x418547ae
    3: "321210321202"
    4: 1
  }
  21: "224331203202B3032134622431RT002026610"
  22: "K3202537{O271273374K351376224310*"
  22: "300336d(224kL25224300355256247327R35"
  22: "303O:202330262A32624623307D314F303G"
  22: "210"22?250|L.272375345{335c,26"
  22: "=3yP2604N33426737732036F326331\"
  22: "E21100246e6EI22300)2423348216M"
  22: "V#26322367324H350232r1310_KX273"
  23: "320232320276320273320270321207320265321201321202320262320276"
  24: 1
}

5 Формируем .proto файл
Используем номера из предыдущего пункта, по контенту из предыдущего пункта нужно догадаться, какие поля, что означают (например 3 — это ссылка на изображение продукта)

Методом проб и ошибок получаем следующую структуру:

syntax = "proto2";

message Offers {
  repeated Offer offer = 1;
}

message Offer {
  optional string name = 2;
  optional string image_url = 3;
  optional float price_before = 4;
  optional float price_after = 5;
  optional float amount = 8;
  optional float discount = 10;
  optional string start_date = 15;
  optional string end_date = 16;
}

4 Переходим к написанию кода

Создаем питоновский файл с описанием структуры из .proto файла
protoc --proto_path=proto_files --python_out=proto_structs offers.proto

proto_files — имя директории с .proto файлами
proto_structs — в этой директории сохраняются результаты (_pb2.py файлы)

Код работает следующим образом:

  1. Делает запрос к API сайта
  2. Преобразует ответ сайта в json
  3. Выводит результат

import json
import requests

from google.protobuf.json_format import MessageToJson
from proto_structs import offers_pb2

def parse_page(city = "moskva", shop = "5ka", page_num = 1):
    """
    :param city: location of the shop
    :param shop: shop name
    :param page_num: parsed page number
    :return: None
    """
    url = f"https://squark.edadeal.ru/web/search/offers?count=30&locality={city}&page={page_num}&retailer={shop}"
    data = requests.get(url, allow_redirects=True)  # data.content is a protobuf message

    offers = offers_pb2.Offers()  # protobuf structure
    offers.ParseFromString(data.content)  # parse binary data
    products: str = MessageToJson(offers)  # convert protobuf message to json
    products = json.loads(products)
    print(json.dumps(products, indent=4, ensure_ascii=False,))

if __name__ == "__main__":
    parse_page()

Результат работы программы — список продуктов с описанием

{
    "offer": [
        {
            "name": "Наггетсы, куриные с ветчиной, Мираторг, 300 г",
            "imageUrl": "https://leonardo.edadeal.io/dyn/cr/catalyst/offers/necnmkv43splbm3hr5636snpry.jpg",
            "priceBefore": 218.99000549316406,
            "priceAfter": 109.48999786376953,
            "amount": 300.0,
            "discount": 51.0,
            "startDate": "2022-08-02T00:00:00Z",
            "endDate": "2022-08-08T00:00:00Z"
        },
        ...

5 Сравним результаты

Время выполнения кода из предыдущего пункта 0.3 — 0.4 секунды
Альтернативный вариант парсинга — загрузка всего html-кода страницы и извлечения нужной информации из этого кода

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://edadeal.ru/moskva/retailers/5ka")
# извлечение данных из html кода

Время полной загрузки страницы 5 — 6 секунд.

6 Выводы

Лучше использовать API сайта для извлечения данных, если есть такая возможность
Использование API сайта позволяет не зависеть от изменений в html-коде страниы

Введение в API

В системе реализованы 2 механизма для работы API 

  • Входящий запрос к методу API платформы  – внешняя система обращается по определенному endpoint платформы по HTTPS GET/POST и получает некий отклик в JSON/XML/Plain text формате.
  • Исходящий запрос к внешним системам – система подготавливает запрос к внешней системе (URL, параметры формы, HTTP заголовки и др.) в процедуре Request, отправляет его по HTTPS GET/POST и обрабатывает ответ в процедуре Response. 

Подготовка исходящих запросов, обработка отклика от исходящих запросов, обработка входящих запросов – вся обработка происходит через хранимые процедуры. 

Некоторые готовые интеграции на базе платформы:

  • Различные интеграции в документации
  • Примеры интеграции на Демостенде

Варианты интеграции с внешним API

Есть несколько вариантов/уровней интеграции: 

1. Вызов неких действий через кнопку Формы.

Используем процедуру SaveItem формы для вызова Внешнего действия apirequest, которое непосредственно выполняет запрос к внешней среде. 

Полученный ответ может быть обработан через spCallback (хранимая процедура, которая выполняется после указанного внешнего действия), либо через JS коллбек формы SaveItem (в JS обрабатываем JSON-поле additionalData). 

2. Кастом JS компонент.

Реализовать свой JS компонент, который обращается через Request JS к базе данных. В хранимой процедуре вызываем внешнее действие apirequest, затем обрабатываем отклик через JS. 

3. Подтягивание данных по API из внешней системы при загрузке формы или таблицы. 

Если указан источник у формы, таблицы, то при загрузке таблицы сначала выполняется запрос в внешней системе, затем данные попадают в процедуру GetItems, где вы можете их распарсить и вывести как данные таблицы. 

4. Вебхук. 

Допустим, произошло некое событие в системе. Вызываем в процедурах sync, форме или другом месте внешнее действие apirequest, которое отправляет уведомление (информацию о событии в виде Get/Post запроса) во внешнюю систему. 

5. Прямой доступ к БД 

В некоторых случаях можно интегрировать 2 системы минуя слой API. 

Платформа может обращаться напрямую к другим СУБД (через SQL Server Linked Server). Запросы также будут писаться на SQL как и в обычном случае, но обработка данных будет уже происходить во внешней системе.

Если есть другая БД MS SQL Server, которая лежит на том же сервере, то можно дать права на некие объекты этой БД пользователю платформы. В этом случае работа практически ничем не будет отличаться от случая, когда мы используем родную базу Falcon Space (только префикс будет у таблиц добавляться с именем базы данных). 

Интерфейс управления API в личном кабинете администратора 

Управление API происходит на странице /asapi.

Управление входящими запросами: 

Управление исходящими запросами:

Тестирование запросов по аналогии с Postman (кнопка API Request):

Заполняем URL и параметры запроса (HTTP заголовки, файлы, параметры формы) и получаем отклик внешней системы. 

Что может и не может API платформы

Что может механизм API 

  • Отправлять исходящие запросы GET/POST
  • Отправлять свои HTTP заголовки 
  • Отправлять данные формы
  • Отправлять тело POST запроса в виде JSON
  • Отправлять файлы в POST запросе
  • Проводить тестовые запросы (по аналогии с postman)
  • Делать свой слой API для обращения к ним извне
  • Вводить авторизацию для входящих API запросов по токену(api пользователи и сессионные ключи для доступа, предварительные запросы для получения токена).
  • Логирование API запросов (по каждому запросу сохраняется input и output данные в trace). 

Что не может API платформы

  • Работа в формате SOAP (технически возможно, но очень трудоемко поддерживать сложный XML формат вручную). 
  • Система не использует разделение GET/POST/DELETE/PUT запросов для обработки сущностей по соглашениям REST. Каждый метод выполняет свое бизнес-действие, заложенное в соответствующей хранимой процедуре.

Входящие запросы API

Это слой API платформы, к которому обращается внешняя система через запросы GET/POST.

Как проходит основной процесс входящего запроса: 

  1. Обращение извне по HTTPS GET к методу auth для получения token доступа (система проверяет логин, пароль и выдает токен, который будет проверяться в дальнейших обращениях). 
  2. Отправка запроса action для выполнения некоего действия (Получить заказы, создать новый заказ). В рамках запроса происходит следующее:
    1. Проверяются права на выполнение операции
    2. Запускается хранимая процедура обработки действия, подготавливается ответ для вызывающей стороны в виде JSON, XML, Plain text.
    3. Выдается некий отклик на вызывающую сторону

Всегда лучше использовать коды для API только в нижнем регистре латиницей и без пробелов. Таким образом уменьшаются риски проблем с url rewrite неверных адресов

Для API используются обычные HTTPS запросы с ответом в формате JSON. Основные методы

  • auth – создание сессии пользования API (параметры username, password)

  • action – выполнение некоего метода API (параметры могут быть любые)

Использование API

1. Вызываем по Get или Post метод авторизации /api/auth?username=&password={password}&output=json

  • Имя и пароль пользователя API задается в таблице as_api_users (это не логин/пароль обычного пользователя системы). 

  • output – необязательный параметр, задает формат вывода (json, xml,text).

Если данные корректные, то получим токен в отклике сервера. {“errorCode”:0,”token”:”7285440B-BD32-405F-813D-C26DFED23DF5″,”result”:true,”msg”:””}
Если есть ошибки, то result = false и errorCode содержит код ошибки. 

2. Вызываем метод API 

/api/action/getOrders?token=7285440B-BD32-405F-813D-C26DFED23DF5&catID=1

Передаем token, action (код метода) и произвольные параметры. 

Если все хорошо, то мы получаем result: true и в data содержатся выходные данные от результата выполнения метода. 
Коды ошибок и описания к ним: 

Код

Описание ошибки

1

100

Неверный токен

2

101

Истекло время сессии

3

102

Не найдена реализация метода АПИ (т.е. нет хранимой процедуры метода)

4

103

Выполнение метода завершилось с ошибкой

5

104

Имя/пароль неверные

Примечание: 

  1. в ExtendedDictionaryParameter @parameters используем Key, Value2, а не Key, Value!
  2. в @parameters также передается содержимое самого запроса Request.InputStream (в Key=InputStream)
  3. в @parameters также передается ключ remoteIP – IP вызывающей стороне (например, по нему можно проверить легитимность запроса к API)
  4. Если используете для отправки метод POST, то обязательно указывайте   ‘content-type’: ‘application/x-www-form-urlencoded’. Проверять подобные запросы можно через программу postman.

Создание нового метода API

API создается следующим образом: 

  1. Создается действие в таблице as_api_actions (на странице /asapi)

  • entityCode указывает код сущности, с которой мы работаем, например order.
  • code – задает код действия. 

    2. Создается хранимая процедура api_{entityCode}_{code}, которая реализует основную логику метода API. 

CREATE procedure [dbo].[api_order_getOrders]
@parameters ExtendedDictionaryParameter READONLY, -- параметры которые переданы в метод
@username nvarchar(256) --пользователь API (это не логин пользователя в системе)
as
begin
	declare @catID int
	select @catID = cast(Value2 as int) from @parameters where [Key] = 'catID'

	/* select 1 - это информация об операции. В errorCode можно указать
          специфичные коды ошибок по операциям */
	select '' Msg, 1 Result, 0 errorCode, 0 onlyData

	/* select 2 - это данные, которые необходимо передать источнику запроса к API
        (в выходном JSON передаются в параметре data) */
	select * from ord_orders


        /* SELECT 3 Вызов внешних действий (напр Запрос API)*/

end

На входе: 

  • @parameters – входные параметры в API метод (что приходит из URL, из полей формы и коллекции Httpheaders). Также здесь хранится тело запроса с кодом Key = “InputStream”
  • @username  – логин API (важно его не путать с логином пользователя в системе). 

На выходе: 

  • SELECT 1:
    • результат операции (Result),
    • код результата (errorCode),
    • HTTP код ответа  (httpCode, по умолчанию идет 200),
    • редирект на какой-то адрес (redirectUrl),
    • onlyData – если 1, то для JSON и XML вывода данные будут формироваться чисто из данных из SELECT 2
  • SELECT 2 – произвольные данные, которые передаются вовне. 
  • SELECT 3 – Вызов внешних действий (уведомление на почту, телеграм и др.)

3.Вызываем метод как /api/action/actioncode1?token=token1&…{доп. параметры}….

Вызов API без авторизации

В этом случае нет необходимости использовать токены.

  • У action укажите параметр withoutToken=true.

  • Вызывайте метод без токена: /api/action/getOrders?catID=1

Установка формата вывода для действия. 
Для этого укажите json,text или xml в параметре outputType для действия (as_api_actions). 

Cвойство идемпотентности для создаваемых методов API

Для включения идемпотентности необходимо в запросе к API передавать определенный параметр или заголовок(например X-Request-ID), содержащий уникальный идентификатор: guid, комбинация из номера заказа, даты и суммы.
Каждый новый запрос, который необходимо обработать, должен включать новое значение X-Request-ID.
Таким образом можно избежать проблем с повторными запросами (когда операция дважды выполнится на сервере для 1 запроса).

Иногда требуется учесть в выходном сообщении результаты выполнения внешних действий, в этом случае необходимо задействовать дополнительную процедуру _result – https://falconspace.ru/docs/vkhodyashchiy-api–kak-uchest-v-otklike-rezultat-vneshnikh-deystviy-v-api

Исходящие запросы к внешним API

Вы можете обратиться к внешним API через использование Внешних действий (код apirequest, использование описано в документации по Формам). 
Чтобы создать запрос, необходимо выполнить следующее:

  • создать запись о новом запросе (таблицы Исходящие запросы API на /asapi)

  • реализовать процедуру request(она выдает адрес и параметры для выполнения запроса)

    • На входе: @parameters ExtendedDictionaryParameter (коллекция входных параметров в Key nvarchar(32), Value2 nvarchar(max))  и @username (текущий пользователь)

    • Возвращает SELECT 1 (Msg, Result и URL, ContentType)

      • URL – адрес, который будет вызван по HTTPS
      • RequestParameterForResponse – некая строка, которую потом можно извлечь в процедуре respose по одноименному ключу из @parameters.  В исходящий запрос эта информация не идет. 
      • ContentType – можно задать для POST запросов свой ContentType (для формы).
        • По умолчанию он подставляется для форм multipart/form-data; boundary=——
        • и для json тела application/json
    • и SELECT 2 (параметры которые будут передаваться вовне – name, value, type). 

      • type – вариант form, header, json.

        • Если отправить надо post запрос, то параметры ставьте в form.

        • Если передан json (используется для POST, имя можно также ставить в JSON) – то его содержимое будет телом всего запроса POST. Все остальные параметры типа Form в этом случае игнорируются (при этом параметры типа headers не игнорируются).

        • Если нужны обычные get параметры – то передавайте их через URL

  • реализовать процедуру обработки ответа – response

    • На входе ответ от внешнего источника в виде строки @response, @parameters ExtendedDictionaryParameter (коллекция входных параметров в Key, Value2, которые приходили в Request процедуру. Сюда также приходит от Request параметр RequestParameterForResponse)

    • Ответ

      • SELECT 1 Msg, Result и Response (может быть дополнительная обработка и выдача ответа вовне). 

      • SELECT 2 Вызов внешних действий (Внешние запросы API и т.д.)
  • вызвать запрос через внешние действия (при сохранении формы, отправке уведомления или других местах).

Ответ при вызове API, например, из формы, передается в поле Response из SELECT 1. 

Туда можно передать полностью входную переменную @response без обработки, или результаты парсинга переменной @response в доступном для понимания виде.

Для тестирования API можно использовать метод /Api/Req/{code} – он вернет ответ в JSON формате. 

Пример хранимой процедуры request: 

CREATE PROCEDURE [dbo].[api_metrikaMonth_request]
	@parameters ExtendedDictionaryParameter READONLY,  -- входящие параметры для внутренней обработки (используйте Key, Value2)
	@username nvarchar(32)  -- текущий пользователь.
AS
BEGIN


declare @metrikaID nvarchar(256)
	set @metrikaID = '53312170' -- Falcon

--set @metrikaID = '60713749' -- DEMO

declare @date1 nvarchar(256) = convert(nvarchar(10), dateadd(day, -30, getdate()), 120)  --2020-04-26
declare @date2 nvarchar(256) = convert(nvarchar(10), getdate(), 120)


declare @token nvarchar(256) = 'token...'
declare @url nvarchar(512) = 'https://api-metrika.yandex.net/stat/v1/data/bytime?'
    	+ 'id='+@metrikaID
    	+ '&preset=sources_summary'
        + '&group=day'
    	+ '&metrics=ym:s:users,ym:s:visits,ym:s:manPercentage,ym:s:womanPercentage' +
        + '&date1=' + @date1   --2020-04-26
    	+ '&date2=' + @date2    -- 2020-04-26
    	-- SELECT 1  Msg, Result, Url (адрес, куда будет идти запрос)
	select '' Msg, 1 Result, @url Url

	-- SELECT 2 PARAMETERS - параметры, которые будут передаваться во внешний источник
--	select 'Content-type' name, 'application/json' value, 'header' [type] -- form (в форме передается), header (в http headers), get запросы передавайте прямо в URL
  --  union
  --  select 'Accept' name, 'application/json' value, 'header' [type]
    --union
    select 'Authorization' name, 'OAuth '+ @token value, 'header' [type]
END

Пример response:

CREATE PROCEDURE [dbo].[api_metrikaMonth_response]
	@response nvarchar(max),
	@parameters ExtendedDictionaryParameter READONLY,  -- входящие параметры для внутренней обработки (используйте Key, Value2 - те же что и на request)

	@username nvarchar(32)
AS
BEGIN
	-- SELECT 1
	select '' Msg, 1 Result, @response Response

	-- SELECT 2 Внешние действия

END


Как отправить исходящий запрос POST с JSON телом?

Для этого указываем тип запроса POST и передаем в процедуре Request в SELECT 2 только 1 параметр с type=json и value =тело запроса в формате строки с JSON.

В этом случае система возмет значение JSON как тело запроса POST. 

Как создать цепочку последовательных запросов? 

Отправляем исходящий запрос. В процедуре response обрабатываем ответ внешней системы и вызываем в ней через SELECT 2 внешнее действие с другим API методом. 

Примечание
Учитывайте длину кодов и ключей (не должны быть больше 32 символов).

Работа с JSON в SQL Server

  • https://docs.microsoft.com/ru-ru/sql/relational-databases/json/json-data-sql-server?view=sql-server-ver15
  • https://stackoverflow.com/questions/2867501/parse-json-in-tsql
  • https://habr.com/ru/post/343062/
  • https://habr.com/ru/post/317166/

Работа с XML в SQL Server 

  • https://stackoverflow.com/questions/15680259/parse-xml-in-sql-server/15681388
  • https://stackoverflow.com/questions/3989395/convert-xml-to-table-sql-server

Онлайн редакторы для XML и JSON

Инструменты позволяют скопировать большой текст и просматривать через дерево элементов.

  • https://xmlgrid.net/ – просмотр XML
  • https://jsoneditoronline.org/ – редактор JSON

Функции, полезные для API 

В SQL есть набор полезных функций, которые выполняют стандартные преобразования 

as_md5 – генерирует хеш строку MD5. Пример: dbo.as_md5(‘123’)

as_hmac – генерирует хеш код в SHA1 и других форматах (https://ru.wikipedia.org/wiki/HMAC).  Пример: 

 select dbo.as_hmac('SHA1', convert(varbinary(max), @secret), 
	 convert(varbinary(max), @data ))

Важно, чтобы @secret и @data были varchar(max), а не nvarchar(max)

as_strToBase64 – генерирует значение в кодировке base64. Если на входе varbinary(max), то преобразуем специальным образом: 

select dbo.as_strToBase64(lower(convert(nvarchar(max), @sh1, 2))) 

as_NCharToUTF8Binary – преобразуем строку nvarchar в binary(max).  

fn_PBKDF2 – стандарт формирования ключа на основе пароля. https://ru.wikipedia.org/wiki/PBKDF2

На практике возникает множество нюансов и возвращаемые функции могут давать не совсем тот результат – это зависит от формата входных данных (varbinary, nvarchar или varchar, lower or not). Проверяйте промежуточные тестовые данные через онлайн сервисы: 

HMAC Service https://freeformatter.com/hmac-generator.html#ad-output

MD5 Online https://decodeit.ru/md5/

Base64 Online https://decodeit.ru/base64/

Falcon Space – функциональная веб-платформа разработки на узком стеке MS SQL/Bootstrap. Вводная по Falcon Space

Насколько полезной была статья?

Google поиск по нашей документации

Many APIs are publicly available. All APIs on the RapidAPI platform are publicly available. But there are also so-called internal APIs, which are created and used by developers that need APIs for private applications.

When it comes to web and mobile applications, there is a process to follow in order to determine what API the website uses. In some cases, you can also use the internal API without interacting with the website (i.e. programmatically, by issuing requests directly from the code). In this tutorial, we will demonstrate how to find an API of a website.

View the Best Free APIs List

How websites use APIs

There are two main ways in which websites use APIs. For the sake of keeping things simple, we’ll call them the backend-tied method and frontend-tied method.

The backend-tied approach is the method where the application makes requests to the API on the server’s side. The pipeline looks like this: 

  1. The user wants to visit a page of the website. He/she uses a browser to send an HTTP request to the server where the site is hosted. 
  2. To provide a response to the user, the server needs to use an API.
  3. The server sends the request(s) to the API and processes the response of the API. The response to the user is prepared using the response of the API.
  4. The server sends the prepared response (most often it is the HTML page) to the user.
  5. The user’s browser renders the response and shows the result to the user.

The key peculiarity of this method is that the user’s browser knows nothing about what is going on on the server’s side (how the response was prepared). This means that we (as users) cannot detect whether any API was used by this site. The exception comes in when the information about used APIs are available on the website, or when t is obvious that the website uses an API (for example, when the website displays information about flight tickets from the Skyscanner).

A vivid example of the backend-tied approach of API usage can be found in our How To Build a Sentiment Analysis App tutorial. The Django web application there sends requests to the API on the server’s side.

Another method is the frontend-tied approach

Most modern web frameworks use client-side rendering. They send a blank HTML file to the browser along with JavaScript that fills it with data. In this case, it takes data from the internal API. And this is handy for us because if it is done with our browser we can find it. Let’s explore how this works in more detail.

How to see whether a website uses an API

Let’s create a little sandbox to demonstrate how it works. We can use Flask to make a simple internal API which will send only one string of text data. The ‘Access-Control-Allow-Origin’ header is added so we can simply open the HTML file in the browser and make this request from it.

from flask import Flask
from flask import jsonify
from flask import after_this_request


app = Flask(__name__)


@app.route('/test_data', methods=['GET'])
def get_data():
   @after_this_request
   def add_header(response):
       response.headers['Access-Control-Allow-Origin'] = '*'
       return response

   data = 'An internal API is an interface that enables access to a company’s backend information and application functionality for use by the organization’s developers. The new applications created by these developers can then be distributed publicly although the interface itself is not visible to anyone not working directly with the API publisher.'
   return jsonify(data)


if __name__ == '__main__':
   app.run(debug=True)

Then we will write an HTML page that will request this string and view it.

<!DOCTYPE html>
<html>
 <head>
   <meta charset="utf-8">
   <title>Test page</title>
 </head>
 <body>
  <h1>Hello world</h1>
  <p id="text"></p>
  <script>
       const text_el = document.getElementById('text')
       const url = 'http://127.0.0.1:5000/test_data'
       fetch(url)
       .then((resp) => resp.json())
       .then(function(data) {
         text_el.innerHTML = data
       })
   </script>
 </body>
</html>

If we open this page in the browser and view the page source code we will not see the data and this is typical for a frontend-tied approach using the API. If it was not a test page, we wouldn’t see the script either.

Let’s go back to our page in the browser and open the Developer Tools.

Now we need to open the Network tab and choose the XHR filter. XHR refers to the XMLHttpRequest which is the JavaScript object that is used to retrieve data from a server. (We actually use the fetch() request but it’s almost the same.) In some cases, we’ll need to repeat an action or refresh the page to see requests here. With real sites, there could also be a lot of requests. We need to choose the ones that look similar to what we expect to find.

find api devtools

If we click on a request we’ll see the full URL, the HTTP method, and any other necessary information. With our page, we see the “http://127.0.0.1:5000/test_data” address and the GET method.

find api in browser

Now we can open the Response tab and suppose that the data is what we are looking for.

find api browser response

All that we still need to do is to simply make a similar request programmatically and check if we get the same answer.

Test your hypothesis from Python code

Python has a Requests library that is ideal for this purpose. For our example, the code will look pretty simple.

import requests


url = 'http://127.0.0.1:5000/test_data'
response = requests.get(url)
print(response.text)

Here is what the code above returns:

"An internal API is an interface that enables access to a companyu2019s backend information and application functionality for use by the organizationu2019s developers. The new applications created by these developers can then be distributed publicly although the interface itself is not visible to anyone not working directly with the API publisher."

But Requests itself has a lot more options. Any other HTTP method can be used with requests the same way as the GET method. We may also add data to the request body.

In most cases, we’ll get our response in JSON or XML format, so we’ll need to make some transformations or parsing.

Conclusion

There are two ways in which websites can use APIs. If we can see the data on the page but can’t find it in the page source, that’s okay. Finding an API with browser tools is not that complicated. Working with it may be easier than writing parsers for the HTML.

But if we can’t see requests from the browser it does not mean that the site doesn’t use API. If it sends server-side requests we may have trouble finding out which API a website uses.

View the Best Free APIs List

The best place to find out about a JSON-based API is the documentation provided by API’s maintainer. Typically, maintainers who would like their API to be consumed by clients provide documentation. Sometimes, they build a navigable API where responses have http links to other resources of their API and do not provide an explicit documentation. If they do so, that could be called as implicit documentation.

Networks tab in a web browser’s developers’ tools provides a way to capture network traffic going in and out of the browser. If a website makes any asynchronous http request, that will be captured and shown here. Again depending on the design and strategy of the website maker, this could be a JSON based response coming from a URL or a HTML or any other type. Content-Type header hints at the type of response. You can use this cue as well to see if the content of the response is application/json. Thus, obtaaining a url that you can use in your scripts.

What you are trying to do here is observing a website’s network traffic from your browser and are trying to see if there is any link that brings you a JSON based response instead of HTML. So, that you can use a JSON parser instead of a HTML parser. Possibly, because HTML parsers are slow.

The Answer to your specific question is, if you get lucky you might find a link that serves a JSON response. If not, you might wanna fall back on HTML parsing.

Чтобы искать с помощью API Яндекс.Поиска для сайта, вам необходимо получить ключ и подключить его к своему поиску.

Чтобы получить ключ авторизации:

  1. Перейдите на страницу Кабинета разработчика.

  2. Нажмите на кнопку Получить ключ и заполните поля:

    • Имя ключа — имя, которое отображается на странице Ваши API-ключи. Его будете видеть только вы.

    • Сервис для подключения — выберите API Яндекс.Поиска для сайта.

В результате будет создан уникальный ключ авторизации для доступа к API Яндекс.Поиска для сайта. Вы можете создать несколько ключей для разных поисков. Перечень ключей доступен на странице Ваши API-ключи сервиса Яндекс.Кабинет разработчика.

Чтобы подключить ключ авторизации к поиску:

  1. Перейдите на страницу Мои поиски сервиса Яндекс.Поиск для сайта.

  2. Выберите поиск из списка. Если у вас еще нет поиска по интернет-магазину, создайте его.

  3. В поле API-ключ на странице Выдача в JSON укажите значение ключа авторизации и сохраните изменения.

Изменения вступают в силу в течение часа после сохранения.

Внимание. Ключ авторизации можно использовать для доступа только к одному поиску. Попытка подключить один ключ к двум и более поискам вызовет ошибку.

Добавить комментарий