Теперь давайте научимся разбирать нашу таблицу. Обратим внимание, что у таблицы есть заголовок с указанным в ней годом, есть строка, состоящая из ячеек с заголовками и есть строки с данными. Также обратим внимание, что строка с данными выглядит всегда одинаково: если в этой строке есть данные, то в первом столбце будет название города, во всех остальных столбцах будут данные о среднемесячной зарплате. Давайте превратим нашу таблицу в словарь. Пусть в этом словаре будут ключами города, ключей у нас будет четыре штуки, а ячейки с данными пусть лежат в списках, которые в нашем словаре будут значениями — получится такой словарь в списках. Чтобы превратить таблицу в словарь, пройдем по нашим страницам, найдем там тег-таблицы для каждой ячейки, для каждой строки, посмотрим на ее ячейки, если это ячейки с данными, то с помощью проверки методом "isdigit()" мы сможем понять: эта ячейка с данными о начисленной зарплате или это ячейка с названием города. У меня есть шаблон для программы, где уже подключен модуль "Requests", подключен модуль "Beautiful Soup", есть наша чудесная функция, которая скачивает страницу из Интернета, настраивает и готовит к работе, есть адрес одной из страниц нашего сайта и HTML-код нашего сайта уже загружен в переменную "Soup". Давайте посмотрим, как компьютер внутри HTML-кода видит наши таблицы на сайте. Для этого попросим его сначала найти для нас таблицу, в нашем случае таблица на сайте всего одна, и тег "table" тоже всего один, можем просто попросить его найти. Давайте пройдем по всем строчкам в этой таблице. Для этого попросим компьютер пройти по всем тегам "tr" из найденных внутри нашей таблицы и пока просто попросим распечатать строчки на экран. Обратим внимание, что строчки с информацией используют теги "tr", внутри которых есть только теги "td", строчки с заголовками используют теги "tr", и внутри них есть теги "th". Строчка с заголовками нас не интересует, нас интересуют только ячейки с данными, поэтому давайте доработаем нашу программу, скопируем текущую полностью, и в новой следующей ячейке попросим компьютер не просто распечатать нашу строчку, HTML-код каждой из строчек, но найти в этих строчках теги "td", теги с данными и пройти по всем ячейкам с данными. Для этого мы внутри каждой строки попросим найти все возможные ячейки с данными, так как в первой строке ячеек с данными просто нет, там нет ни одного тега "td", там есть только теги "th", там внутренний цикл для первой строки не выполнится. Давайте посмотрим на ячейки с данными, вернее, на их HTML-код. Здорово! Единственное, чем отличаются ячейки с данными, с названиями городов, так это тем, что в них нет цифр, поэтому доработаем нашу программу, скопировав в новую ячейку прошлую программу в полном объеме, и вместо вывода на экран HTML-кода ячейки попросим компьютер узнать, состоит ли содержимое ячейки только из цифр. Для этого обратимся к тексту внутри ячейки, и если текст состоит только из цифр, то это информация о среднемесячной зарплате, если не только из цифр, то это информация про город. Давайте сначала создадим ключ, то есть обработаем ситуацию, когда в ячейке есть не только цифры. Если в ячейки есть не только цифры, то это новый город, и мы можем в наш словарь с таблицей этот город добавить. Изобретем для себя словарь, расположим его где-нибудь повыше, над циклами, пока его сделаем пустым, и теперь создадим новое значение в этом словаре. Пока в качестве значений у нас будет пустой список — получается словарь списков, где ключом будет название города, а значением будет список из всех значений среднемесячной начисленной заработной платы. Если же в ячейке есть только цифры, то это будет значение, и его нужно в соответствующий список зарплат соответствующего города добавить. При этом, так как компьютер будет обрабатывать HTML-код последовательно, мы всегда сначала встретимся с названием города и создадим наш ключ, и только потом мы увидим значение, которое будет нужно к этому ключу прикреплять. Так как зарплата — это числа, давайте прямо здесь преобразуем данные о зарплатах из строки в число, после чего можно посмотреть, какие данные удалось извлечь из одной страницы. Для этого пройдем по всем городам в получившемся словаре и для каждого города выведем его название и список из зарплат. Посмотрим, как это работает. Чудесно, много данных, и они аккуратно расфаршированы по нужным для нас ключам и значениям. Давайте сравним, что написанные данные из нашей собственной программы совпадают с данными, указанными на сайте. Нам нужно для этого открыть главную страницу: как видите, данные действительно совпадают. Чудесно! Давайте теперь упакуем наш код, вытаскивающий таблицу с сайта и превращающий ее в слова, в функцию, потому что это полезно и это позволит нам повторно использовать этот код. Наша функция будет принимать в себя переменную с найденной с помощью ее Beautiful Soup таблицы, а возвращать будет в словарик, который состоит из названий городов и списка значений зарплат. Скопируем текст, который вытаскивает таблицу с сайта и преобразует в словарь, я оформлю его как функцию, и, наверное, назовем ее "Распознай таблицу в словарь". Поправим отступы, чтобы компьютер понял, что теперь это все является функцией, в принципе практически ничего не поменялось, наша функция принимает переменную "table" с найденной таблицей и возвращает в ту же самую таблицу, но уже не в виде HTML-кода, а в виде словаря. Итак, мы добавили название нашей функции, поправили отступы, добавили команду возврата, благодаря которой функция сможет что-то полезное вернуть в основную программу. Давайте теперь посмотрим, что функция действительно работает. Для этого скопируем прошлую программу и весь код обработки таблицы заменим на вызов нашей функции. Добавим нашу функцию наверх, чтобы она у нас была, и обратимся к функции, чтобы получить словарь. Никакой другой код не менялся. Итак, раньше мы обрабатывали таблицу самостоятельно, теперь мы вынесли это в функцию. Объявление "Функция" мы положили над нашей программой, и теперь мы просто создаем переменную со словарем списков нашей таблицы и просим нашу функцию этот словарь для нас создать. Посмотрим, что в выводе ничего не поменялось. Чудесно, теперь мы не просто умеем извлекать данные из таблицы, мы еще и сделали себе функцию.