Данная статья предназначена для тех, кто работает с анализом поискового продвижения в Яндекс или занимается рекламой в директ. Полученные здесь регионы используются так же в объявлениях (Директ) и могут быть полезны при написании программ для работы с API Директ. Так же регионы можно использовать в отчетах Яндекс Метрики для получение статистики только по определенным регионам, если этого требует задача.

Ниже я расскажу, как получить актуальный список регионов, но для этого необходим доступ к API Яндекс Маркета.

Письмо в службу поддержки
Я написал в поддержку xml.yandex.ru с просьбой предоставить список регионов или добавить возможность поиска региона через это же API. Ответ получил достаточно быстро, но ничего нового не узнал. Поддержка предложила использовать список регионов, выложенный в открытый доступ по ссылке: yandex.ru/yaca/geo.c2n.

Также они отметили, что предоставлять доступ к списку регионов у них нет возможности (впрочем это подразделение API «XML», вероятно не имеет доступа к списку регионов, хотя и использует их коды в своем функционале).

Как получить список всех регионов
Ранее я уже находил в интернете несколько архивов со списком регионов за 2009 и 2011 года, но опять-таки все они были неполные.

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

Я начал подготовку к написанию скрипта и обнаружил, что в этом каталоге отсутствуют некоторые населенный пункты (города / деревни).

Поискав в различных API Яндекса была найдена функция в API «Яндекс Маркет», для получения необходимых регионов. Используя это API можно получить не только города, но и их районы и даже список станций метро (правда зачем это может понадобиться неизвестно).

Получение полного актуального списка регионов


MySql - Структура таблицы для хранения регионов
CREATE TABLE `regions` (
  `id` int(11) NOT NULL,
  `google_id` int(11) DEFAULT NULL,
  `mail_id` int(11) DEFAULT NULL,
  `coords` varchar(32) NOT NULL,
  `countryCode` varchar(2) NOT NULL,
  `type` varchar(24) NOT NULL,
  `name_ru` varchar(64) NOT NULL,
  `areaName_ru` varchar(64) NOT NULL,
  `name_en` varchar(64) NOT NULL,
  `areaName_en` varchar(64) NOT NULL,
  `childrenCount` smallint(6) NOT NULL,
  `parentId` int(11) NOT NULL,
  `status` tinyint(1) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


MySql - данные первого родительского региона
INSERT INTO `regions` (`id`, `google_id`, `mail_id`, `coords`, `countryCode`, `type`, `name_ru`, `areaName_ru`, `name_en`, `areaName_en`, `childrenCount`, `parentId`) VALUES
(10000, NULL, NULL, '', '', 'OTHER', 'Земля', '', '', '', 8, 0, 0)


PHP функция для получение регионов
Функция получается для родительского региона все регионы — потомки. После этого ее необходимо вызвать еще раз, для получения подпотомков и т.д.
usleep() — необходимо для соблюдения ограничений API Маркета (не более 10 запросов в секунду).

// Возможные типы регионов:
// CONTINENT — континент;
// REGION — регион;
// COUNTRY — страна;
// COUNTRY_DISTRICT — федеральный округ;
// SUBJECT_FEDERATION — субъект федерации;
// CITY — город;
// VILLAGE — поселок, село, деревня;
// CITY_DISTRICT — район города;
// METRO_STATION — станция метро;
// OTHER — другой тип населенного пункта.
function import_regions(){
	$api_key = 'ВАШ_КЛЮЧ';
	$limit = 30;

	$regions_ids = dbh()->sel('`id`')->from('regions')->where('`status` = 0')->limit(1000)->fetchAll(PDO::FETCH_COLUMN);
	$regions_ids = 1000;

	foreach($regions_ids as $region_id){
		$page = 1;
		$count_pages = 1;

		while($page <= $count_pages){
			$url = "http://api.partner.market.yandex.ru/v1/georegion/$region_id/children.json?count=$limit&page=$page&api_key=$api_key";

			$res = m('user')->get_content_new($url);
			$res = json_decode($res);
			if(isset($res->errors)){
				echo $res->errors[0];
				exit();
			}

			foreach($res->georegions->items as $item){
				if($item->id == -1) continue;

				$data = array(
					'id' => $item->id,
					'name_ru' => $item->name,
					'parentId' => $item->parentId,
					'childrenCount' => $item->childrenCount,
					'type' => $item->type,
					'status' => ($item->childrenCount == 0)
				);

				echo $item->name.'<br>';
				dbh()->insert('regions')->set($data, true)->exec();
				usleep(100000);
			}

			$count_pages = ceil($res->georegions->total / $limit);
			$page++;
		}

		dbh()->update('regions')->set(array('status' => 1))->where("`id` = '$region_id'")->exec();
	}
}


Список регионов Яндекса (только страны, области и населенные пункты)
Файл состоит из 5 колонок: id|name|region_name|coutryCode|type|parentId. Всего около 25000 регионов.
Список регионов Яндекса (.csv в .zip).

Комментарии (6)


  1. barker
    07.01.2016 20:43

    В 1251 — это по каким-то идеологическим соображениям или там так изначально было?


    1. Artemeey
      07.01.2016 20:45
      +1

      Сперва был сделан для открытия в Excel. Скорее всего будет правильным в utf-8.


  1. affka
    07.01.2016 20:50

    Яндекс же предложил вам парсить самому, соответственно и пользоваться самому, а не выкладывать на всеобщее обозрение.


    1. Artemeey
      07.01.2016 21:15
      +3

      Парсить не пришлось, API Яндекса предоставляет список всех регионов.


      1. Topvisor
        08.01.2016 10:31

        В статье не описан способ получения доступа к API Яндекс Маркет.


        1. Artemeey
          08.01.2016 11:40

          Для получения партнерского доступа нужно иметь свой интернет магазин:


          Более подробно здесь.

          Если у вас нет своего интернет магазина, возможно воспользоваться сторонними сервисами, делегирующими свой доступ к API маркета своим клиентам.