Python/XML RSS Feedparser — пустые поля

Я пытаюсь разобрать RSS-канал погоды NOAA. У меня есть скрипт, который отлично извлекает записи, но некоторые поля пусты, и я не могу понять, почему. Кажется, это проблема с более сложными типами данных в фиде. Вот код:

url = 'http://alerts.weather.gov/cap/us.php?x=1'
feed = feedparser.parse(url)
print 'title: ', feed.entries[0].title
print 'cap_geocode: ', feed.entries[0].cap_geocode
print 'cap_event: ', feed.entries[0].cap_event

Вот результаты печати записи:

title:  Flood Watch issued June 18 at 5:00AM AKDT until June 21 at 4:00PM...
cap_geocode:  
cap_event:  Flood Watch

Я не могу понять, почему cap_geocode пуст. Любая идея? Вот файл xml только с одним элементом. Фид на самом деле возвращает 100 записей или записей, поэтому я сократил его до небольшой выборки.

<feed
xmlns = 'http://www.w3.org/2005/Atom'
xmlns:cap = 'urn:oasis:names:tc:emergency:cap:1.1'
xmlns:ha = 'http://www.alerting.net/namespace/index_1.0'
>

<id>http://alerts.weather.gov/cap/us.atom</id>
<logo>http://alerts.weather.gov/images/xml_logo.gif</logo>
<generator>NWS CAP Server</generator>
<updated>2014-06-18T08:22:00-06:00</updated>
<author>
<name>[email protected]</name>
</author>
<title>Current Watches, Warnings and Advisories for the United States Issued by the National Weather Service</title>
<link href='http://alerts.weather.gov/cap/us.atom'/>
    <entry>
    <id>http://alerts.weather.gov/cap/wwacapget.php?x=WY12515A62F544.WinterWeatherAdvisory.12515A71D320WY.RIWWSWRIW.8dcf1ff2519d541d79867824b0480d63</id>
    <updated>2014-06-18T02:57:00-06:00</updated>
    <published>2014-06-18T02:57:00-06:00</published>
    <author>
    <name>[email protected]</name>
    </author>
    <title>Winter Weather Advisory issued June 18 at 2:57AM MDT until June 19 at 12:00AM MDT by NWS</title>
    <link href='http://alerts.weather.gov/cap/wwacapget.php?x=WY12515A62F544.WinterWeatherAdvisory.12515A71D320WY.RIWWSWRIW.8dcf1ff2519d541d79867824b0480d63'/>
    <summary>...WINTER WEATHER CONTINUES TO IMPACT THE WESTERN AND CENTRAL MOUNTAINS THROUGH MIDNIGHT.</summary>
    <cap:event>Winter Weather Advisory</cap:event>
    <cap:effective>2014-06-18T02:57:00-06:00</cap:effective>
    <cap:expires>2014-06-19T00:00:00-06:00</cap:expires>
    <cap:status>Actual</cap:status>
    <cap:msgType>Alert</cap:msgType>
    <cap:category>Met</cap:category>
    <cap:urgency>Expected</cap:urgency>
    <cap:severity>Minor</cap:severity>
    <cap:certainty>Likely</cap:certainty>
    <cap:areaDesc>Absaroka Mountains; Teton and Gros Ventre Mountains</cap:areaDesc>
    <cap:polygon></cap:polygon>
    <cap:geocode>
    <valueName>FIPS6</valueName>
    <value>056013 056017 056023 056029 056035 056039</value>
    <valueName>UGC</valueName>
    <value>WYZ002 WYZ012</value>
    </cap:geocode>
    <cap:parameter>
    <valueName>VTEC</valueName>
    <value>/O.CON.KRIW.WW.Y.0031.000000T0000Z-140619T0600Z/</value>
    </cap:parameter>
    </entry>    
</feed>

Любая помощь будет оценена по достоинству. Спасибо

*Update Я убедился, что cap_geocode — это пустая строка юникода нулевой длины, а не какой-либо объект.


person Hoopdady    schedule 18.06.2014    source источник


Ответы (2)


Кажется, вы должны monkeypatch feedparser . ..к сожалению, синтаксический анализатор xml, похоже, не анализирует атрибуты для cap_geocode.

Я не эксперт по xml, но ElementTree также не анализирует атрибуты для cap_geocode.

В какой-то момент я перестал с этим бороться и просто написал:

from bs4 import BeautifulSoup
import requests

url = 'http://alerts.weather.gov/cap/us.php?x=1'

r = requests.get(url)
soup = BeautifulSoup(r.text, 'xml')
entries = soup.find_all('entry')

geocode = {}
k = None
for tag in entries[0].geocode.children:
    if tag.name == 'valueName':
        k = tag.string
    elif tag.name == 'value':
        geocode[k] = tag.string

print 'title: ', entries[0].title.string
print 'cap_geocode: ', str(geocode)
print 'cap_event: ', entries[0].event.string
person willo    schedule 25.06.2014
comment
Ух ты. Мне потребовалась целая вечность, чтобы заставить скрипт работать из-за некоторых зависимостей, но он работает! - person Hoopdady; 25.06.2014

Итак, ваша переменная cap_geocode на самом деле указывает на узел с дочерними элементами в RSS-канале:

<cap:geocode>
   <valueName>FIPS6</valueName>
   <value>056013 056017 056023 056029 056035 056039</value>
   <valueName>UGC</valueName>
   <value>WYZ002 WYZ012</value>
</cap:geocode>

Итак, вам, вероятно, придется сделать что-то более сложное, например, feed.entries[0].cap_geocode[0].valueName[0] для доступа к FIPS6, feed.entries[0].cap_geocode[0].valueName[1] для доступа к UGC, feed.entries[0].cap_geocode[0].value[0] для доступа к 056013 056017 056023 056029 056035 056039 и feed.entries[0].cap_geocode[0].value[1] для доступа к WYZ002 WYZ012.

person Julien Genestoux    schedule 18.06.2014
comment
На самом деле feed.entries[0].cap_geocode — это строка юникода длиной 0. Так что это не сработает. Проблема, похоже, в том, что он не захватывает данные. Вы можете убедиться сами. Вам нужно будет установить feedparser, а затем импортировать его, но скрипт, который я разместил, работает. - person Hoopdady; 18.06.2014