На информационном ресурсе применяются рекомендательные технологии (информационные технологии предоставления информации на основе сбора, систематизации и анализа сведений, относящихся к предпочтениям пользователей сети "Интернет", находящихся на территории Российской Федерации)

GeekBrains

4 подписчика

Быстрый старт с Go: сканер погоды

Продолжаем знакомиться с языком Go. В этот раз напишем программу, способную читать в интернете данные о погоде, — своего рода сканер погоды. Предварительно рекомендую прочитать статью «Быстрый старт с Go: первые шаги» — для нашей сегодняшней задачи вам потребуется знать основы языка, а также скачать и установить компилятор Go.

План работы над нашим сканером таков:

  • используем сайт, который выдаёт прогноз погоды в формате XML,
  • прочитаем оттуда данные по погоде средствами Go,
  • преобразуем их в удобный для обработки формат,
  • выберем то, что нам необходимо.

Настраиваем источник информации

Мы воспользуемся сайтом «Метеосервис», который позволяет получать информацию о погоде в выбранной стране и указанном городе. Чтобы получить нужную ссылку, переходим на страницу настройки сервиса. Выберем из списков страну и город — например, Россию и Москву. В результате чуть ниже, после слов «Местоположение сервиса», видим ссылку: https://xml.meteoservice.ru/export/gismeteo/point/32277.xml. Этот адрес возвращает в XML-формате информацию о погоде в выбранном городе. Его можно даже просто открыть в браузере. Ещё на странице настройки сервиса есть описание структуры получаемых данных.

Читаем данные с сайта

Для чтения данных по полученной ссылке используем GET-запрос по протоколу HTTP. Для отправки запросов в Go в пакете net/http определено несколько функций, по одной на каждый вид запроса. Нам нужна функция Get().

В качестве параметра она принимает адрес ресурса, к которому надо выполнить запрос, и возвращает объект http.Response, содержащий ответ сервера. Как и все функции, связанные с вводом-выводом, Get() вернёт ошибку, если она возникнет. 

Фрагмент кода с использованием Get() и обработкой ошибок будет выглядеть так:

 response, err := http.Get("https://xml.meteoservice.ru/export/gismeteo/point/32277.xml") if err != nil {     log.Fatal(err) } defer response.Body.Close() 

Последняя строка фрагмента содержит команду отложенного закрытия потока Body. Не забываем при этом импортировать соответствующие пакеты:

 import (     "net/http"     "log" ) 

Поле Body структуры http.Response представляет собой ответ от веб-ресурса и при этом является интерфейсом io.ReadCloser. Фактически это поле — поток для чтения, и его можно прочесть как массив байт, используя функцию ReadAll() пакета io/ioutil. Применим для этого следующий код, не забыв импортировать соответствующий пакет:

 byteValue, err := ioutil.ReadAll(response.Body) if err != nil {     log.Fatal(err) } 

Результат можно легко вывести, к примеру, в консоль, преобразовав массив байт в строку:

 fmt.Print(string(byteValue)) 

Формат данных XML и структуры

XML (eXtensible Markup Language) — это расширяемый язык разметки. В отличие от языка гипертекстовой разметки HTML, который содержит ограниченный набор тегов, XML позволяет разработчику использовать собственные теги.

В пакет библиотеки Go encoding/xml входят функции, позволяющие работать с XML. Нам потребуется функция xml.Unmarshall, преобразующая XML-данные в соответствующую структуру.

Структуры в Go — это специальный тип данных, определяемый разработчиком и служащий для описания какого-либо объекта. Структуры содержат набор полей, которые представляют различные атрибуты объекта. Для определения структуры применяются ключевые слова type и struct. Каждое поле имеет имя и тип, как переменная.

 type person struct {     name string     age int } 

Предложенная выше структура, к примеру, описывает человека. Её имя — person. Она содержит два поля: name (имя человека, представляет тип string) и age (возраст человека, представляет тип int).

Распаковываем XML в структуру

Полученные с сайта XML-данные необходимо распаковать в структуру, имеющую поля, соответствующие тегам в наших данных. Создадим её с помощью онлайн-инструмента. Вводим адрес, по которому читаем XML, в строку — и нажимаем кнопку Get from URL. Или копируем полученный XML в левое окно. При этом в правом окне генерируется соответствующая структура на Go. Копируем её в свой код. Рекомендую внимательно изучить её поля и увидеть их соответствие XML-данным.

Затем объявляем переменную, типом которой будет наша структура. В эту переменную распаковываем полученные из интернета данные в формате XML, используя функцию xml.Unmarshal().

 var weather MMWEATHER err = xml.Unmarshal(byteValue, &weather) if err != nil {     log.Fatal(err) } 

Выбираем информацию из структуры

После распаковки переменная weather содержит в виде структуры данные, которые мы получили в формате XML. Для обращения к полям структуры используется точка. К примеру, чтобы вывести значения поля Sname, которое содержит название города, нужно написать:

 fmt.Println(url.PathUnescape(weather.REPORT.TOWN.Sname)) 

То есть обратиться к полю Sname структуры TOWN, которая является полем структуры REPORT, выступающей в свою очередь полем переменной weather. Кроме того, нужно использовать функцию url.PathUnescape(), чтобы раскодировать значение этого поля. И не забыть при этом импортировать пакет net/url.

А если, к примеру, мы хотим получить все значения прогнозируемой максимальной температуры, достаточно использовать следующий фрагмент кода:

 forecast := weather.REPORT.TOWN.FORECAST for i := 0; i < len(forecast); i++ {     fmt.Println("T.Max:", forecast[i].TEMPERATURE.Max) } 

Если нужно уточнить дату и время прогноза, достаточно добавить следующую строку в тело цикла:

 fmt.Printf("Day: %s/%s %s:00\n", forecast[i].Day, forecast[i].Month, forecast[i].Hour) 

Исследуя полученные XML и структуры, мы видим, что данные содержат также информацию о давлении, направлении, силе ветра и так далее. Чтобы поупражняться, можно попробовать вывести в консоль и эту информацию.

Заключение

Если у вас всё получилось — поздравляю! Если нет и возникли вопросы — пишите, спрашивайте, не стесняйтесь. Меня можно найти в Telegram под ником @biblelamp или на сайте GeekBrains. Желаю всем удачи и рекомендую никогда не останавливаться в изучении программирования.

Дополнительные материалы по Go для начинающих:

Первая часть цикла о Go-разработке:

Хотите получить системную подготовку? На факультете Go-разработки GeekUniversity вы за полтора года приобретёте все знания, необходимые для начала карьеры Go-разработчика, создадите собственное портфолио из нескольких работ и получите работу по специальности.

Самоизоляция заканчивается — самое время освоить новую профессию, чтобы начать карьеру мечты и уверенно смотреть в будущее! Мы хотим помочь вам и с 11 по 21 июля 2020 г. дарим скидку 40% почти на все программы обучения GeekBrains. Будьте здоровы и успешны! :)

 

 

Ссылка на первоисточник
наверх