При написании своего сервиса SEO аналитики, он же личный кабинет клиента, была поставлена задача получить список федеральных округов, регионов, районов и городов с содержанием идентификаторов Яндекса. Поискав в интернете ничего готово не нашел, так что кому-нибудь данная статья пригодится.
Есть два пути решения как получить список регионов:
1) С помощью API Яндекс директ – выгружается сразу в формате JSON, но что бы получить доступ к API требуется пройти проверку. Так что такой вариант не подходит, нужно еще сделать скрин интерфейса программы (думаю если отскринить скрип, модератор не оценит юмор);
2) Отпарсить html c сайта – самый быстрый и простой вариант.
Первым делом нужно узнать где в html «прячется» наши регионы. Открыв браузер выяснилось, что список регионы загружается с помощью AJAX при клике по ссылке «Все регионы»
Мы теперь знаем ссылку для получения списка регионов:
https://wordstat.yandex.ru/stat/regions_tree
Написание парсера Яндекс wordstat на Python
Для этих целей нам потребуется 4 модуля, именно:
- «Requests» – для получения html, установить можно командой;
pip install requests
- «BeautifulSoup» – этот модуль нужен для разбора html и поиска нужных узлов DOM по селекторам, а также библиотека для парсинга html5lib, передается в конструктор BeautifulSoup в качестве второго аргумента в виде строки. Не забываем установить модули:
pip install html5lib pip install bs4
- Модуль «re» для работы с регулярными выражениями;
- Модуль «json» для вывода полученного результата в виде json строки.
Импортируем модули:import requests from bs4 import BeautifulSoup import re import json
Создадим три переменные
headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:45.0) Gecko/20100101 Firefox/45.0' } url = "https://wordstat.yandex.ru/stat/regions_tree" result = []
headers – заголовок агента, чтобы нас не заблокировали;
url - адрес списка регионов;
result – список словарей регионов, который мы получим в результате парсина.
Пишем функцию для парсинга:
def get_region(): if len(result) > 0: return result session = requests.Session() r = requests.get(url, headers=headers) dom = BeautifulSoup(r.text, "html5lib") region = dom.find(id="beginRegions") def get_tree(group, parent): for item in group: if item.name == 'div': if re.match("^region", item['id']): idparse = re.findall(r'region(\d+)', item['id']) result.append({ 'title': item.label.string, 'id': int(idparse[0]), 'parent': int(parent) }) get_tree(item.children, idparse[0]) get_tree(region, 0) return result
get_tree – это рекурсивная функция, которая обходит дочерние узлы и добавляет в наш результирующий список.
Все работает осталось выгрузить полученный список в файл, используем для этого код самопроверки:
if __name__ == '__main__': res = get_region() with open("yandex_region.json", "w") as file: json.dump(res, file)
И еще одна полезная пункция «строит» результат в виде дерева в json bild_tree():
def bild_tree(): if len(result) == 0: get_region() tree = [] def tree_recursive(id, node={}): for item in result: if item['parent'] == id: if 'id' in node: if not 'children' in node: node['children'] = [] new_node = item.copy() tree_recursive(item['id'], new_node) if 'children' in new_node and len(new_node['children']) == 0: del new_node['children'] node['children'].append(new_node) else: new_node = item.copy() tree_recursive(item['id'], new_node) tree.append(new_node) tree_recursive(0) return tree
Написание такого скрипта заняло не больше 10 минут, что намного меньше, если бы мы проходили всю процедуру регистрации API Яндекс.Директа. В следующих уроках расскажу, как авторизоваться в Яндекс для парсинга ключевых слов и обхода каптчи. Подпишись на рассылку, чтобы узнать первым.