Python-Parsing
-
03-07-2019 - |
Frage
Ich versuche, den Titel-Tag in ein RSS 2.0 Feed in drei verschiedene Variablen für jeden Eintrag in diesem Feed zu analysieren. Mit ElementTree Ich habe analysiert bereits den RSS, so dass ich jeden Titel drucken [minus den Hinter )
] mit dem folgenden Code:
feed = getfeed("http://www.tourfilter.com/dallas/rss/by_concert_date") for item in feed: print repr(item.title[0:-1])
Ich schließe das, weil, wie Sie sehen können, die item.title eine repr ist () Datentyp, die ich weiß nicht viel über.
Eine besondere repr(item.title[0:-1])
im interaktiven Fenster print
ed sieht wie folgt aus:
'randy travis (Billy Bobs 3/21' 'Michael Schenker Group (House of Blues Dallas 3/26'
Der Benutzer wählt eine Band und ich hoffe, nach jedem item.title
in 3 Parsen von Variablen (je einem für Band, Ort und Datum ... oder möglicherweise ein Array oder ich weiß nicht, ...) wählt nur diejenigen, bezogen ausgewählt zum Band. Dann werden sie für die Geokodierung an Google gesendet, aber das ist eine andere Geschichte.
Ich habe einige Beispiele für regex
gesehen und ich über sie gerade lese, aber es scheint sehr kompliziert. Ist es? Ich dachte, vielleicht hier jemand einen Einblick, genau haben würde, wie dies auf intelligente Art und Weise zu tun. Sollte ich das re
Modul verwenden? Spielt es eine Rolle, dass der Ausgang derzeit repr()
s ist? Gibt es einen besseren Weg? Ich dachte, dass ich wie eine Schleife verwenden würde (und das ist mein pseudoPython, nur eine Art von Notizen, die ich bin Schrift):
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
Am Ende, ich brauche die ausgewählten Einträge in einer CSV haben (kommagetrennte Datei) wie folgt aussehen:
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
Ich hoffe, das ist nicht zu viel zu fragen. Ich werde schauen hinein auf meinem eigenen, dachte nur, soll ich hier schreiben, um sicherzustellen, es beantwortet wurde.
Also, die Frage ist, wie ich am besten jedes repr(item.title[0:-1])
im feed
in die 3 separate Werte analysieren, die ich dann in eine CSV-Datei verketten kann?
Lösung
Lassen Sie sich nicht regex abschrecken ... es lohnt sich zu lernen.
Die genannten Beispiele, Sie könnten versuchen, die hintere Klammer wieder einlegen und dann mit diesem Muster:
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')
Um bei jeder Gruppe individuellen zu bekommen, so dass sie nur ruft das info
Objekt:
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"
Die harte Sache über Regex in diesem Fall dafür, dass Sie alle bekannten möglichen Zeichen im Titel kennen. Wenn es nicht-alpha Zeichen in der ‚Michael Schenker Group‘ Teil sind, werden Sie die Regex für den Teil einstellen müssen, um ihnen zu ermöglichen.
Das Muster oben setzt sich wie folgt, die links nach rechts analysiert wird:
([\w\s]+)
: jedes Wort oder Leerzeichen Match (das Plus-Symbol zeigt an, dass es ein oder mehr solche Zeichen lang sein). Die Klammern bedeuten, dass das Spiel als Gruppe aufgenommen wird. Dies ist die „Michael Schenker Group“ teil. Wenn es hier Zahlen und Bindestriche werden kann, sollten Sie die Stücke zwischen den eckigen Klammern ändern, die die möglichen Zeichen für den Satz sind.
\(
: Eine wörtliche Klammer. Der Backslash entkommt die Klammer, da sonst zählt es als regex. Dies ist der „(“ Teil der Zeichenfolge.
([\w\s]+)
: Das gleiche wie die oben, aber diesmal stimmt mit dem „House of Blues Dallas“ -Teil. In den Klammern so werden sie als die zweite Gruppe aufgenommen werden.
(\d+/\d+)
: Spiele der Ziffern 3 und 26 mit einem Schrägstrich in der Mitte. In den Klammern so werden sie als dritte Gruppe aufgenommen werden.
\)
. Schließen Klammer für die oben
Das Python Einführung in regex ist recht gut, und Sie könnten einen Abend gehen über sie http://docs.python.org/library/re.html#module-re . Überprüfen Sie auch Dive Into Python, die eine freundliche Einführung hat: http://diveintopython3.ep.io /regular-expressions.html .
EDIT: Siehe zacherates unten, die ein paar nette Änderungen hat. Zwei Köpfe sind besser als einer!
Andere Tipps
Reguläre Ausdrücke sind eine gute Lösung für dieses Problem:
>>> 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')
Als Randbemerkung, könnte man auf der Seite Universal-Feed-Parser für den Umgang mit dem RSS-Feeds als Parsing haben eine schlechte Gewohnheit mißgebildeter werden.
Bearbeiten
In Bezug auf Ihre Kommentar ... Die Saiten gelegentlich in „als s eher eingewickelt‚hat s mit der Tatsache zu tun, dass Sie repr verwenden. Die repr einer Zeichenkette in der Regel mit begrenzten‘s, es sei denn, dass Zeichenfolge enthält eine oder mehrere ‚s, wo statt es„s verwendet, so dass die ‚s muß nicht entgangen sein:
>>> "Hello there"
'Hello there'
>>> "it's not its"
"it's not its"
Beachten Sie die verschiedenen Kursarten.
Im Hinblick auf die repr(item.title[0:-1])
Teil, nicht sicher, wo Sie bekam, dass aus, aber ich bin mir ziemlich sicher, dass Sie einfach item.title
verwenden können. Alles, was Sie tun, ist das letzte Zeichen aus der Zeichenfolge zu entfernen und dann repr()
und fordert sie auf, die nichts tut.
Der Code sollte wie folgt aussehen:
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)
Bearbeiten : ersetzt list
mit lines
als var name. list
ist ein builtin und sollte nicht als Variablennamen verwendet werden. Es tut uns Leid.