пятница, 30 марта 2012 г.

О том как написать программу на lua для приема сводок погоды с любого сайта. Часть 3


Вытаскиваем данные текущей погоды




Снова открываем файл pogoda и ищем строку примерно такого содержания

<h1><small>Weather Report and Forecast for</small><br>

Далее следуют данные текущей погоды, а за конечную точку я взял такую строку

<div class="col2">

и так же как и для прогноза забираем данные погоды в переменную nowweather

-- забираем данные для текущей погоды
local a,b,nowweather = string.find(allweatherdata, "<div class=\"col1\">(.*)<div class=\"col2\">")

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

now = {}

Начнем забирать данные о дне, месяце, числе, годе, времени, которые вообщем то и не нужны, но я хочу показать как из строки содержащей множество данных выбрать одно значение. Возьмем строку

<div class="dateTime">Monday, March 26th 2012, 11:50 GMT</div>

и заменим в ней все данные на специальные символы, о них я упоминал в Части 2.

<div class="dateTime">%a*%p%s%a*%s%d*%a*%s%d*%p%s%d*%p%d*%s%a*</div>

Для взятия необходимых данных их помещают в скобки, например для названия дня

local s,f,t = string.find(nowweather,"<div class=\"dateTime\">(%a*)%p%s%a*%s%d*%a*%s%d*%p%s%d*%p%d*%s%a*</div>")

и помещаем данные в базу, т.е. создаём ячейку с названием day в базе данных now

now["day"] = t

Забираем месяц

local s,f,t = string.find(nowweather,"<div class=\"dateTime\">%a*%p%s(%a*)%s%d*%a*%s%d*%p%s%d*%p%d*%s%a*</div>")
now["month"] = t

Дату

local s,f,t = string.find(nowweather,"<div class=\"dateTime\">%a*%p%s%a*%s(%d*)%a*%s%d*%p%d*%p%d*%s%a*</div>")
now["date"] = t

Год

local s,f,t = string.find(nowweather,"<div class=\"dateTime\">%a*%p%s%a*%s%d*%a*%s(%d*)%p%s%d*%p%d*%s%a*</div>")
now["year"] = t

Время по гринвичу

local s,f,t = string.find(nowweather,"<div class=\"dateTime\">%a*%p%s%a*%s%d*%a*%s%d*%p%s(%d*%p%d*%s%a*)</div>")
now["time"] = t

Теперь, таким же способом, забираем остальные данные

Иконка погоды находится в строке

<img src="/weather_icons/mostly_cloudy_dl.gif" width="84" height="85">

забираем данные и помещаем в ячейку

local s,f,t = string.find(nowweather, "weather_icons/([%a%p]*).gif\" width")
now["weather_icon"] = t

Так же поступаем и с остальными данными

Состояние погоды

<div class="currentWeather">Mostly Cloudy</div>

local s,f,t = string.find(nowweather, "currentWeather">(%a*)</div>")
now["currentWeather"] = t


Время последнего обновления

<td width="116" class="labelAndValue"><span class="currentLabel">Updated:</span><span class="currentValue">11:00 GMT</span></td>


local s,f,t = string.find(nowweather, "Updated:</span><span class=\"currentValue\">(%d*%p%d*%s%a*)</span></td>")
now["updated"] = t

Температура

<div class="currentTemperature">1&deg;C</div>

local s,f,t = string.find(nowweather, "currentTemperature\">([%p%d]*)&deg")

при записи данных о температуре в базу можно сразу же добавить °C

now["temp"] = t .. "°C"

Скорость ветра в данном прогнозе дана в км/час

<td class="labelAndValue"><span class="currentLabel">Wind Spd:</span><span class="currentValue">36.00 kmh</span></td>

local s,f,kmh = string.find(nowweather, "Wind Spd:</span><span class=\"currentValue\">([%d%p]*)%skmh")

Для вывода скорости ветра в км/час

now["wind_kmh"] = kmh

для вывода скорости ветра в м/сек добавим перерасчет км/час в м/сек, math.seil округляет до целых чисел

now["wind_ms"] = math.ceil(kmh/3.6)  .. " м/с"


Направление ветра в системе NESW

<td class="labelAndValue"><span class="currentLabel">Wind Dir:</span><span class="currentValue">NNW (340&deg;)</span></td>

local s,f,t = string.find(nowweather, "Wind Dir:</span><span class="currentValue">(%a*)%s(%d*&deg;")
now["NESW"] = t

Направление ветра в градусах

local s,f,t = string.find(nowweather, "Wind Dir:</span><span class=\"currentValue\">%a*%s%p(%d*)&deg;")
now["wind_deg"] = t

Давление представлено в гектапаскалях

<td class="labelAndValue"><span class="currentLabel">Pressure:</span><span class="currentValue">1009.00 hPa</span></td>

local s,f,t = string.find(nowweather, "Pressure:</span><span class=\"currentValue\">(%d*%p%d*)%shPa")

в гектопаскалях

now["press_hPa"] = t

производим перерасчет в миллиметры ртутного столба

now["press_mm"] = math.ceil(t/1.33322)  .. " мм.рт.ст"

Точка росы, это температура при которой возникает туман

<td class="labelAndValue"><span class="currentLabel">Dewpoint:</span><span class="currentValue">0&deg;C</span></td>

local s,f,t = string.find(nowweather, "Dewpoint:</span><span class=\"currentValue\">([%p%d]*)&deg")
now["dewpoint"] = t

Ощущаемая температура

<td class="labelAndValue"><span class="currentLabel">Feels Like:</span><span class="currentValue">-6&deg;C</span></td>

local s,f,t = string.find(nowweather, "Feels Like:</span><span class=\"currentValue\">([%p%d]*)&deg")
now["feels_like"] = t .. "°C"

Видимость

<td class="labelAndValue" style="border-bottom: 0px"><span class="currentLabel">Visibility:</span><span class="currentValue">4.40 km</span></td>


local s,f,t = string.find(nowweather, "Visibility:</span><span class=\"currentValue\">([%d%p]*)%skm")
now["visibility"] = t .. " км"

На всякий случай каждый новый вывод значения можно проверять добавляя после значения команду print(t)

Теперь наш скрипт выглядит так

--[[ forecast.lua
скрипт забирает прогноз погоды и обрабатывает его для вывода на экран
]]


require "cairo"


-- адрес сайта
web = "http://www.weatherreports.com/Pavlograd,_Ukraine?units=c"
-- время обновления прогноза погоды
secs = 1800 -- обновление каждые 30 минут ( в секундах )


function conky_forecast ()


-- устанавливаем таймер обновления данных с сайта


local updates = tonumber(conky_parse('${updates}'))
local timer = (updates %secs) + 1
if timer == 1 or updates == 0 then


-- для проверки загоняем в /tmp
-- os.execute("curl --max-time 60 '".. web .."'| sed 's/%//g' >> ~/proba/pogoda1")


-- считываем данные с сайта
local f = io.popen("curl --max-time 60 '"..web.."' | sed 's/%//g'")
-- помещаем в переменную allweatherdata
allweatherdata = f:read("*a")
-- прекращаем считывание
f:close()
-- фильтруем данные в переменной allweatherdata
allweatherdata = string.gsub(allweatherdata, "[\n\r]", "")


-- создаем таблицу для прогноза
forecast_day = {}
weather_icon = {}
high_temp = {}
low_temp = {}
forecastWeather = {}
-- выбираем данные для прогноза
local a,b,allweather = string.find(allweatherdata,"<div class=\"forecastTitle\">(.*)<div style=\"border:1px solid gray;\">")
-- очищаем счетчик
local start = 0
local f = 1
-- сам цикл
while f ~= nil do
-- данные о названии дней
local s,f,t = string.find(allweather, "forecastDayOfWeekTitle\">(%a*)<", start)
-- помещаем данные в таблицу в forecast_day
table.insert(forecast_day, t)
-- данные о состоянии погоды
local s,f,t = string.find(allweather, "dotted #3bb878\">([%a%s]*)<", start)
table.insert(forecastWeather, t)
-- иконка погоды
local s,f,t = string.find(allweather, "weather_icons/([%a%p]*).gif", start)
table.insert(weather_icon, t)
-- наибольшая температура
local s,f,t = string.find(allweather, "High:%s*([%p%d]*)&deg", start)
table.insert(high_temp, t)
-- наинизшая температура
local s,f,t = string.find(allweather, "Low: ([%p%d]*)&deg", start)
table.insert(low_temp, t)
-- если данных больше нет заканчиваем цикл
if f == nil then break end
-- если данные имеются, начинаем сначала
start = f
end


-- забираем данные для текущей погоды
local a,b,nowweather = string.find(allweatherdata, "<div class=\"col1\">(.*)<div class=\"col2\">")


-- создаем таблицу для текущей погоды
now = {}


-- день, время
local s,f,t = string.find(nowweather,"<div class=\"dateTime\">(%a*)%p%s%a*%s%d*%a*%s%d*%p%s%d*%p%d*%s%a*</div>")
now["day"] = t
-- месяц
local s,f,t = string.find(nowweather,"<div class=\"dateTime\">%a*%p%s(%a*)%s%d*%a*%s%d*%p%s%d*%p%d*%s%a*</div>")
now["month"] = t
-- дата
local s,f,t = string.find(nowweather,"<div class=\"dateTime\">%a*%p%s%a*%s(%d*)%a*%s%d*%p%s%d*%p%d*%s%a*</div>")
now["date"] = t
-- год
local s,f,t = string.find(nowweather,"<div class=\"dateTime\">%a*%p%s%a*%s%d*%a*%s(%d*)%p%s%d*%p%d*%s%a*</div>")
now["year"] = t
-- время по гринвичу
local s,f,t = string.find(nowweather,"<div class=\"dateTime\">%a*%p%s%a*%s%d*%a*%s%d*%p%s(%d*%p%d*%s%a*)</div>")
now["time"] = t
-- иконка погоды
local s,f,t = string.find(nowweather, "weather_icons/([%a%p]*).gif\" width")
now["weather_icon"] = t
-- состояние погоды
local s,f,t = string.find(nowweather, "currentWeather\">(%a*)</div>")
now["currentWeather"] = t
-- время последнего обновления
local s,f,t = string.find(nowweather, "Updated:</span><span class=\"currentValue\">(%d*%p%d*%s%a*)</span></td>")
now["updated"] = t
-- температура
local s,f,t = string.find(nowweather, "currentTemperature\">([%p%d]*)&deg")
now["temp"] = t .. "°C"
-- скорость ветра
local s,f,kmh = string.find(nowweather, "Wind Spd:</span><span class=\"currentValue\">([%d%p]*)%skmh")
-- в км/час
now["wind_kmh"] = kmh .. " км/час"
-- в м/сек
now["wind_ms"] = math.ceil(kmh/3.6)  .. " м/с"
-- направление ветра в системе NESW
local s,f,t = string.find(nowweather, "Wind Dir:</span><span class=\"currentValue\">(%a*)%s")
now["NESW"] = t
-- направление ветра в градусах
local s,f,t = string.find(nowweather, "Wind Dir:</span><span class=\"currentValue\">%a*%s%p(%d*)&deg;")
now["wind_deg"] = t
-- давление
local s,f,t = string.find(nowweather, "Pressure:</span><span class=\"currentValue\">(%d*%p%d*)%shPa")
-- в гектопаскалях
now["press_hPa"] = t
-- в миллиметрах ртутного столба
now["press_mm"] = math.ceil(t/1.33322)  .. " мм.рт.ст"
-- точка росы
local s,f,t = string.find(nowweather, "Dewpoint:</span><span class=\"currentValue\">([%p%d]*)&deg")
now["dewpoint"] = t
-- ощущаемая температура
local s,f,t = string.find(nowweather, "Feels Like:</span><span class=\"currentValue\">([%p%d]*)&deg")
now["feels_like"] = t .. "°C"
-- видимость
local s,f,t = string.find(nowweather, "Visibility:</span><span class=\"currentValue\">([%d%p]*)%skm")
now["visibility"] = t .. " км"


end
end

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

В следующий раз будет описание вывода всего этого в окно conky

1 комментарий: