質問
RSS 2.0フィードのタイトルタグを解析して、そのフィードの各エントリの3つの異なる変数にしようとしています。 ElementTreeを使用して、以下のコードで各タイトルを(末尾の)
を除く)印刷できるように、すでにRSSを解析しました:
feed = getfeed("http://www.tourfilter.com/dallas/rss/by_concert_date") for item in feed: print repr(item.title[0:-1])
これを含めるのは、ご覧のとおり、item.titleはrepr()データ型であり、これについてはあまり知りません。
インタラクティブウィンドウに表示される特定の repr(item.title [0:-1])
print
は次のようになります。
'randy travis (Billy Bobs 3/21' 'Michael Schenker Group (House of Blues Dallas 3/26'
ユーザーがバンドを選択し、各 item.title
を3つの変数(バンド、会場、および日付にそれぞれ1つ...または場合によっては配列に解析した後、またはt know ...)選択したバンドに関連するもののみを選択します。その後、ジオコーディングのためにGoogleに送信されますが、それは別の話です。
regex
の例をいくつか見てきましたが、それらについて読んでいますが、非常に複雑に思えます。それは...ですか?多分、ここの誰かがこれをインテリジェントな方法で正確に行う方法についての洞察を持っていると思う。 re
モジュールを使用する必要がありますか?出力が現在 repr()
sであることは重要ですか?もっと良い方法はありますか?私は次のようなループを使用することを考えていました(これは私の擬似Pythonで、書いているメモの一種です):
list = bandRaw,venue,date,latLong for item in feed: parse item.title for bandRaw, venue, date if bandRaw == str(band) send venue name + ", Dallas, TX" to google for geocoding return lat,long list = list + return character + bandRaw + "," + venue + "," + date + "," + lat + "," + long else
最後に、選択したエントリを次のような.csv(コンマ区切り)ファイルに含める必要があります。
band,venue,date,lat,long randy travis,Billy Bobs,3/21,1234.5678,1234.5678 Michael Schenker Group,House of Blues Dallas,3/26,4321.8765,4321.8765
これで質問しすぎないことを望みます。私はそれを自分で調べますが、答えを確実にするためにここに投稿すべきだと思っただけです。
したがって、質問は、 feed
内の各 repr(item.title [0:-1])
を3つの個別の値に最適に解析する方法です。その後、.csvファイルに連結できますか?
解決
正規表現に驚かされないでください...学習する価値があります。
上記の例を考えると、末尾の括弧を元に戻し、このパターンを使用してみてください:
import re
pat = re.compile('([\w\s]+)\(([\w\s]+)(\d+/\d+)\)')
info = pat.match(s)
print info.groups()
('Michael Schenker Group ', 'House of Blues Dallas ', '3/26')
各グループの個人を取得するには、単に info
オブジェクトで呼び出します:
print info.group(1) # or info.groups()[0]
print '"%s","%s","%s"' % (info.group(1), info.group(2), info.group(3))
"Michael Schenker Group","House of Blues Dallas","3/26"
この場合の正規表現の難点は、タイトルに含まれる可能性のあるすべての文字を確実に把握することです。 「Michael Schenker Group」部分に非アルファ文字がある場合、それらを許可するにはその部分の正規表現を調整する必要があります。
上のパターンは次のように分類され、左から右に解析されます:
([\ w \ s] +)
:単語またはスペース文字に一致します(プラス記号は、そのような文字が1つ以上あることを示します)。括弧は、一致がグループとしてキャプチャされることを意味します。これが" Michael Schenker Group"です部。ここに数字とダッシュがある場合は、角括弧の間の部分を変更する必要があります。角括弧は、セットに使用できる文字です。
\(
:リテラル括弧。バックスラッシュは正規表現コマンドとしてカウントされるため、括弧をエスケープします。これは文字列の"("部分です。
([\ w \ s] +)
:上記のものと同じですが、今回は" House of Blues Dallas"と一致します。部。かっこで囲むと、2番目のグループとしてキャプチャされます。
(\ d + / \ d +)
:数字の3と26に一致し、中央にスラッシュがあります。かっこで囲むと、3番目のグループとしてキャプチャされます。
\)
:上記の括弧を閉じます。
正規表現へのpythonイントロは非常に優れているので、一晩過ごして http://docs.python.org/library/re.html#module-re 。また、わかりやすい紹介のあるDive Into Pythonを確認してください: http://diveintopython3.ep.io /regular-expressions.html 。
編集:以下の編集者を参照してください。 2つのヘッドは1つよりも優れています!
他のヒント
正規表現は、この問題の優れた解決策です。
>>> import re
>>> s = 'Michael Schenker Group (House of Blues Dallas 3/26'
>>> re.match(r'(.*) \((.*) (\d+/\d+)', s).groups()
('Michael Schenker Group', 'House of Blues Dallas', '3/26')
補足として、フィードとしてRSS解析を処理するためのユニバーサルフィードパーサーをご覧ください。奇形の悪い習慣を持っている。
編集
あなたのコメントに関して...文字列は、 'sではなく" sでラップされることがありますが、これはreprを使用しているという事実に関係しています。文字列のreprは通常、 'で区切られますが、その文字列に1つ以上の'が含まれる場合は、代わりに"を使用するため、 'をエスケープする必要はありません:
>>> "Hello there"
'Hello there'
>>> "it's not its"
"it's not its"
異なる引用スタイルに注意してください。
repr(item.title [0:-1])
部分については、どこから入手したのかわかりませんが、 item.title
。あなたがしているのは、文字列から最後の文字を削除し、それに対して repr()
を呼び出すだけです。これは何もしません。
コードは次のようになります。
import geocoders # from GeoPy
us = geocoders.GeocoderDotUS()
import feedparser # from www.feedparser.org
feedurl = "http://www.tourfilter.com/dallas/rss/by_concert_date"
feed = feedparser.parse(feedurl)
lines = []
for entry in feed.entries:
m = re.search(r'(.*) \((.*) (\d+/\d+)\)', entry.title)
if m:
bandRaw, venue, date = m.groups()
if band == bandRaw:
place, (lat, lng) = us.geocode(venue + ", Dallas, TX")
lines.append(",".join([band, venue, date, lat, lng]))
result = "\n".join(lines)
編集:変数名として list
を lines
に置き換えました。 list
は組み込みであり、変数名として使用しないでください。ごめんなさい。