Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 19, 2016 22:49:18

Tenebras
Зарегистрирован: 2016-07-05
Сообщения: 97
Репутация: +  0  -
Профиль   Отправить e-mail  

Как из файла "выцепить" нужные данные?

Имеется скрипт:

 #!/usr/bin/python
# coding: utf8
import urllib                          # Подключаем библиотеки для работы с Интернет,
import sys                             # для доступа к параметрам командной строки,
import string                          # для работы со строками
# Индекс ICAO-станции
station = "ULLI"
# Создаем сокет-соединение с сервером
sock = urllib.urlopen("http://aviationweather.gov/metar/data?ids="+station+"&format=raw&hours=0&taf=off&layout=on&date=0")
# Записываем текст HTML-файла в переменную "metar"
metar = sock.read()
# Закрываем сокет-соединение с сервером
sock.close()
# Выводим текст HTML-файла на консоль
#print metar
# Разбиваем текст на отдельные строки
lines = metar.split('\n')
# Задаем начальное значение переменной с признаком наличия строки данных
state = False
# Перебираем все строки
for line in lines:
    # Ищем строку, предшествующую строке с данными METAR-телеграммы
    if line == "<!-- Data starts here -->":
		state = True
		continue
    # Декодируем телеграмму
    if state==True:
		# Берем строку и разбиваем ее отдельные слова (разделитель - символ пробела)
        par = line.split()
        # Извлекаем дату и время
        for i in par:
          if i[-1] == 'Z':
            timeUTC = int(i[2:4])
            strtime = str(timeUTC)
            print strtime+':'+i[4:6],
 
        # Извлекаем значение температуры воздуха
        for i in par:
          if '/' in i:
            temp = i.replace('M','-')
            temp = temp.split('/')[0]+'.0'
            print temp,
            break
 
        # Извлекаем значение атмосферного давления
        for i in par:
          if i[0] == 'Q':
            print i[1:]+'.0'
            break
        # Сбрасываем признак строки с данными
        state = False

Он получает метеоданные ввиде телеграммы.
В html-файле, который обрабатывается важной является только одна строка, содержащая непосредственно текст метео-телеграммы:

ULLI 191930Z 04003MPS 9999 SCT023 11/07 Q1015 R10R/190055 NOSIG

(разумеется текст телеграммы может быть иной, так как погода меняется.

Мне нужно как-то получить данные об облаках. В вышеуказанном примере это “SCT023”. Причём цифры не нужны - нужно лишь вывести на терминал буквы. Их 4 вида. То есть возможны другие варианты, а не только SCT.

Затем нужно будет апгрейдить скрипт и выводить на консоль уже не буквы, а расшифровку.Но мне бы сперва понять - как добиться вывода букв…

И что бы это не выбивалась из того стиля в котором написан скрипт.
Каким образом это сделать?

Отредактировано Tenebras (Сен. 19, 2016 22:49:49)

Офлайн

#2 Сен. 20, 2016 03:33:40

vic57
Зарегистрирован: 2015-07-07
Сообщения: 913
Репутация: +  127  -
Профиль  

Как из файла "выцепить" нужные данные?

сами же написали

Tenebras
if ‘/’ in i:
аналогично
 >>> s = 'qwerty'
>>> 'qwe' in s
True
>>> 'wer' in s
True
>>> 'rty' in s
True
>>>

Офлайн

#3 Сен. 20, 2016 03:35:17

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9891
Репутация: +  854  -
Профиль   Отправить e-mail  

Как из файла "выцепить" нужные данные?

  
>>> import urllib
>>> 
>>> def load_data(url):
...     out = None
...     data = urllib.urlopen(url)
...     for line in data:
...         if 'Data at:' in line:
...             break
...     line = data.readline()
...     if '<!--' in line:
...         line = data.readline()
...         out = line.split('<br', 1)[0]
...     data.close()
...     return out
... 
>>> def get_clouds(data):
...     return data.split()[5]
... 
>>> url = 'http://aviationweather.gov/metar/data?ids=ULLI&format=raw&hours=0&taf=off&layout=on&date=0'
>>> 
>>> data = load_data(url)
>>> data
'ULLI 200000Z 01003MPS 340V040 9999 FEW018CB BKN046 10/09 Q1015 R10R/290050 NOSIG'
>>> clouds = get_clouds(data)
>>> clouds
'FEW018CB'
>>>
Где облака там искать и как, сам определишь. Обычно через регулярные выражения ищут такие вещи.



Отредактировано py.user.next (Сен. 20, 2016 03:37:47)

Офлайн

#4 Сен. 20, 2016 03:43:22

scidam
Зарегистрирован: 2016-06-15
Сообщения: 288
Репутация: +  35  -
Профиль   Отправить e-mail  

Как из файла "выцепить" нужные данные?

Стоит посмотреть в сторону python-metar для парсинга подобных строк: https://pypi.python.org/pypi/metar/1.4.0

Можно попробовать использовать регулярные выражения :

 import re
yourstr = 'STC27389'
repat = re.compile('([A-Z]+)(\d+)')
repat.findall(yourstr)

Чтобы выделить подходящий блок можно воспользоваться split:
 youstr = full_metar_string.split()[4]

Офлайн

#5 Сен. 20, 2016 07:39:24

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Как из файла "выцепить" нужные данные?

Tenebras
И что бы это не выбивалась из того стиля в котором написан скрипт.
А откуда такое условие? Вам лучше выбиться из этого стиля.

  • Стиль основан на построчном чтении. Для html это крайне ненадежный подход. По быстрому лучше использовать регулярки (import re). Может оказаться удобно использовать lxml
  • Скрипт одна кишка. Обычно принято выделять функции, например для парсинга параметров, для вывода данных и т.п. см отличный пример py.user.next
  • В скрипте совершенно не предусмотрено его повторное использование как модуля откройте if __main__ … Это будет мешать его встраиванию в более сложные системы
  • Вывод данных при помощи print в большинстве случаев приведет к тому что люди после вашего скрипта опять будут плеваться и создавать новый парсер, поскольку никакого готового не будет под рукой. Для выдачи данных воспользуйтесь json,yaml и т.п. Принято размечать выдаваемые данные стобы потом мучительно не вспоминать что это за вторая цифра
  • дату время тоже не надо вручную в виде абы чего через две точки писать. Для обработки этих данных в питоне есть модуль datetime.



Отредактировано doza_and (Сен. 20, 2016 07:44:31)

Офлайн

#6 Сен. 20, 2016 13:52:10

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9891
Репутация: +  854  -
Профиль   Отправить e-mail  

Как из файла "выцепить" нужные данные?

doza_and
Стиль основан на построчном чтении. Для html это крайне ненадежный подход. По быстрому лучше использовать регулярки (import re). Может оказаться удобно использовать lxml
У него там поломанный html. Я вообще видел html в исполнении индуса (настоящего), где был тег <html>, но не было тега </html>. И вся страница, если её так можно назвать вообще, была вот в таких вещах. А понял я, что там такое, очень поздно, так как уже написал программу, которая почему-то всё время выпадала на некоторых страницах сайта. Так что и lxml может сломаться на абсолютно диких страницах.

А недавно парсил сайт (ну, как недавно, полтора года уже прошло), где посреди текста просто какая-то вставка какого-то тега типа <br>, просто посреди слова. И он причём нафиг не нужен, потому что от него ничего не меняется. (Перенос по словам, вроде, есть такой тег.) Вот тоже непонятно, как его туда засунули вообще и зачем.



Отредактировано py.user.next (Сен. 20, 2016 13:55:40)

Офлайн

#7 Сен. 20, 2016 15:17:13

vic57
Зарегистрирован: 2015-07-07
Сообщения: 913
Репутация: +  127  -
Профиль  

Как из файла "выцепить" нужные данные?

для METAR есть библиотека, все там расписано.
Или

pip install metar

Отредактировано vic57 (Сен. 21, 2016 08:42:24)

Офлайн

#8 Сен. 20, 2016 18:17:35

vic57
Зарегистрирован: 2015-07-07
Сообщения: 913
Репутация: +  127  -
Профиль  

Как из файла "выцепить" нужные данные?

 #!/usr/bin/env python
# coding: utf8
import urllib
from metar import Metar
def load_data(url):
    out = None
    data = urllib.urlopen(url)
    for line in data:
         if 'Data at:' in line:
             break
    line = data.readline()
    if '<!-- Data starts here -->' in line:
        line = data.readline()
        out = line.split('<b', 1)[0]
    data.close()
    return out
if __name__=="__main__":
    st="http://aviationweather.gov/metar/data?ids=ULLI&format=raw&hours=0&taf=on&layout=off&date=0"
    s = load_data(st)
    ods = Metar.Metar(s)
    print ods.string()

 >>> 
station: ULLI
type: routine report, cycle 15 (automatic report)
time: Tue Sep 20 15:00:00 2016
temperature: 15.0 C
dew point: 8.0 C
wind: N to ENE at 10 knots
visibility: greater than 10000 meters
pressure: 1018.0 mb
sky: scattered clouds at 3100 feet
METAR: ULLI 201500Z 02005MPS 350V060 9999 SCT031 15/08 Q1018 R10R/190055
R10L/090060

Отредактировано vic57 (Сен. 20, 2016 18:19:01)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version