4

我正在尝试将 RSS 2.0 提要中的标题标签解析为该提要中每个条目的三个不同变量。使用 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]) printed 如下所示:

'randy travis (Billy Bobs 3/21'
'Michael Schenker Group (House of Blues Dallas 3/26'

用户选择一个乐队,我希望在将每个变量解析item.title为 3 个变量(乐队、场地和日期各一个......或者可能是一个数组,或者我不知道......)之后,只选择与乐队相关的那些选择。然后将它们发送到 Google 进行地理编码,但这是另一回事。

我看过一些例子,regex我正在阅读它们,但它似乎非常复杂。是吗?我想也许这里有人会对如何以一种智能的方式做到这一点有一些见解。我应该使用该re模块吗?输出当前是repr()s 是否重要?有没有更好的办法?我在想我会使用这样的循环(这是我的伪Python,只是我正在写的一种笔记):

     列表 = bandRaw、地点、日期、latLong  
     对于提要中的项目:  
      为 bandRaw、地点、日期解析 item.title  
       如果 bandRaw == str(band)   
        将场地名称+“,达拉斯,德克萨斯”发送到谷歌进行地理编码  
        返回纬度,经度  
      list = list + return character + bandRaw + "," + place + "," + date + "," + lat + "," + long  
     别的  

最后,我需要在 .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

我希望这不是太多的要求。我会自己研究它,只是想我应该在这里发帖以确保它得到答复。

所以,问题是,我如何最好repr(item.title[0:-1])地将每个值解析feed为 3 个单独的值,然后我可以将它们连接成一个 .csv 文件?

4

3 回答 3

17

不要让正则表达式吓跑你......它非常值得学习。

鉴于上面的示例,您可以尝试将尾括号放回原处,然后使用以下模式:

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”部分中有非 alpha 字符,您必须调整该部分的正则表达式以允许它们。

上面的模式分解如下,从左到右解析:

([\w\s]+):匹配任何单词或空格字符(加号表示应该有一个或多个这样的字符)。括号表示匹配将作为一个组被捕获。这是“Michael Schenker Group”的一部分。如果这里可以有数字和破折号,您需要修改方括号之间的部分,这是该集合的可能字符。

\(: 一个字面括号。反斜杠转义括号,否则它被视为正则表达式命令。这是字符串的“(”部分。

([\w\s]+): 和上面一样,但这次匹配的是“达拉斯蓝调之家”部分。在括号中,因此它们将被捕获为第二组。

(\d+/\d+): 匹配数字 3 和 26,中间有一个斜线。在括号中,因此它们将被捕获为第三组。

\): 上面的右括号。

正则表达式的 python 介绍非常好,您可能想花一个晚上来了解它http://docs.python.org/library/re.html#module-re。另外,请查看 Dive Into Python,它有一个友好的介绍:http ://diveintopython3.ep.io/regular-expressions.html 。

编辑:见下面的 zacherates,他有一些不错的编辑。三个臭皮匠顶个诸葛亮!

于 2009-03-03T19:35:41.917 回答
7

正则表达式是解决这个问题的好方法:

>>> 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 解析的Universal Feed Parser,因为 Feed 有格式错误的坏习惯。

编辑

关于您的评论...字符串偶尔被包裹在 "s 而不是 's 与您使用 repr 的事实有关。字符串的 repr 通常用 's 分隔,除非该字符串包含一个或多个 's,而它使用 "s 以便不必对 's 进行转义:

>>> "Hello there"
'Hello there'
>>> "it's not its"
"it's not its"

注意不同的报价风格。

于 2009-03-03T19:35:51.947 回答
0

关于这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)

编辑:替换listlinesvar 名称。list是内置的,不应用作变量名。对不起。

于 2009-03-03T20:22:36.750 回答