Найти - Пользователи
Полная версия: Как из файла "выцепить" нужные данные?
Начало » Центр помощи » Как из файла "выцепить" нужные данные?
1
Tenebras
Имеется скрипт:

 #!/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.

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

И что бы это не выбивалась из того стиля в котором написан скрипт.
Каким образом это сделать?
vic57
сами же написали
Tenebras
if ‘/’ in i:
аналогично
 >>> s = 'qwerty'
>>> 'qwe' in s
True
>>> 'wer' in s
True
>>> 'rty' in s
True
>>>
py.user.next
  
>>> 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'
>>>
Где облака там искать и как, сам определишь. Обычно через регулярные выражения ищут такие вещи.
scidam
Стоит посмотреть в сторону 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]
doza_and
Tenebras
И что бы это не выбивалась из того стиля в котором написан скрипт.
А откуда такое условие? Вам лучше выбиться из этого стиля.

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

А недавно парсил сайт (ну, как недавно, полтора года уже прошло), где посреди текста просто какая-то вставка какого-то тега типа <br>, просто посреди слова. И он причём нафиг не нужен, потому что от него ничего не меняется. (Перенос по словам, вроде, есть такой тег.) Вот тоже непонятно, как его туда засунули вообще и зачем.
vic57
для METAR есть библиотека, все там расписано.
Или
pip install metar
vic57
 #!/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
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB