2009-03-03 5 views
4

RSS 2.0 피드의 제목 태그를 해당 피드의 각 항목에 대한 세 가지 변수로 구문 분석하려고합니다. 당신이 볼 수 있기 때문Python 구문 분석

내가 포함
feed = getfeed("http://www.tourfilter.com/dallas/rss/by_concert_date") 

for item in feed: 
print repr(item.title[0:-1]) 

에서, item.title임을 A : 각 제목 [뺀 뒤 )] 아래의 코드를 인쇄 할 수 있도록 ElementTree를 사용하여 난 이미 RSS를 분석했습니다 repr() 데이터 형식에 대해서는 많이 알지 못합니다.

대화 창에 특정 repr(item.title[0:-1])print ED는 다음과 같다 :

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

사용자가 밴드를 선택하고, I는 희망 3 개 변수 (대역 장소 각각 하나씩, 및로 각각 item.title 파싱 후 날짜 또는 아마도 배열 또는 모르겠다 ...) 선택한 밴드와 관련된 것들만 선택하십시오. 그런 다음 지오 코딩을 위해 Google에 전송되지만 다른 이야기입니다.

나는 regex의 몇 가지 예를 보았으며 그 내용을 읽었지만 매우 복잡해 보입니다. 그렇지? 나는 지적인 방법으로 정확하게 이것을하는 방법에 관해서는 여기에있는 누군가가 약간의 통찰력을 가지고있을 것이라고 생각했다. re 모듈을 사용해야합니까? 출력이 현재 repr() s입니까? 더 좋은 방법이 있습니까? 나는 (내가 쓰고 있어요이 메모의 단지 종류, 내 pseudoPython이다) 내가 좋아하는 루프를 사용하는 거라고 생각했다 :

 

    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 파일로 연결할 수 있습니까?

답변

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" 

이 경우 regex의 어려운 점은 제목에 알려진 모든 가능한 문자를 알고 있는지 확인하는 것입니다. 'Michael Schenker Group'부분에 알파가 아닌 문자가있는 경우이를 허용하도록 해당 부분의 정규 표현식을 조정해야합니다.

왼쪽에서 오른쪽으로 구문 분석되어, 다음과 같이 패턴이 위 아래로 나누기 :

([\w\s]+) : 어떤 단어 나 공백 문자를 매치 (더하기 기호는 하나 개 이상의 같은 문자가되어야 함을 나타냅니다). 괄호는 일치 항목이 그룹으로 캡처됨을 의미합니다. 이것은 "Michael Schenker Group"부분입니다. 여기에 숫자와 대시가있을 수 있다면 대괄호 사이의 부분을 수정할 수 있습니다. 대괄호는 세트의 가능한 문자입니다.

\( : 리터럴 괄호. 백 슬래시는 괄호를 이스케이프합니다. 그렇지 않으면 정규 표현식 명령으로 간주되기 때문에 괄호를 이스케이프 처리합니다. . 위의 것과 동일하지만,이 시간 부분 "블루스 댈러스의 집"과 일치하는 괄호 그들은이 두 번째 그룹으로 캡처 할 수 있도록

:이

([\w\s]+) 문자열의 "("부분입니다..

(\d+/\d+)은 : 중간 슬래시 숫자 3, 26 일치 괄호들이 제 3 그룹으로 캡처 될 수 있도록

\) :.. 상기 대해 괄호 닫기

정규식 파이썬 소개한다. 꽤 좋은데, 저녁에 오븐을 보내고 싶을 수도 있습니다. 그것 http://docs.python.org/library/re.html#module-re. 또한 친숙한 소개 인 Python으로 다이브를 확인하십시오 : http://diveintopython3.ep.io/regular-expressions.html.

편집 : 아래의 zacherates를 참조하십시오. 편집자는 멋진 편집을했습니다. 한명 보단 두명이 낫다!

+0

답변 해 주셔서 감사합니다. 그게 많은 도움이됩니다! 나는 약간 혼란 스럽다. 필드를 개별적으로 식별하여 Google에 보내고 연결해야한다. 각 값을 어떻게 호출합니까? 예를 들어, 값을 연결하는 방법은? – Alan

+0

정규식은 밴드 및 장소 이름에 후행 공백을 남기지 만 쉽게 수정할 수 있습니다. –

+0

네, 그 점도 알아 챘지만 각'item.title'의 처음 두 값에'[0 : -1] 트릭을 넣었습니다. – Alan

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보고 할 수 있습니다.

편집 귀하의 코멘트에 관해서

... 가끔 "에 싸여중인 문자열의 것은 당신에 repr를 사용하고 있다는 사실과 관련이있다보다는에요. 캐릭터의에 repr입니다

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

공지 사항 다른 인용 스타일 다음의 이스케이프 할 필요가 없도록 대신이 "의 사용의 '해당 문자열이 하나 이상 포함하지 않는 한들'의 일반적로 구분.

+0

답변 해 주셔서 감사합니다. 쪽지에 관해서는, 필자는 항목 중 일부가 ""보다는 시작과 끝으로 나와 있음을 알았습니다. 이것이 문제가되는지 궁금합니다. http://effbot.org/zone/element-rss-wrapper.htm에있는 RSS 파서를 사용했습니다. – Alan

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) 

편집가 : var에 이름과 lines으로 list을 교체했다. list은 내장되어 있으므로 변수 이름으로 사용하면 안됩니다. 죄송합니다.

+0

::: sigh ::: 내가 수입 한 것보다 적은 줄로 모든 것을 쓴 것처럼 보입니다 ... 어떤 모듈을 사용하고 있습니까? 특히 get_geo와 list.append를 위해서? 목록은 __builtin__, 맞습니까? get_geo? GeoPy에서 나온거야? – Alan

+0

마지막 줄에 줄 바꿈이 추가됩니까? 도움이됩니다. 시간을내어 주셔서 감사합니다. – Alan

+0

미안하지만 명확하지 않은 경우 get_geo를 작성했습니다. 방금 구현 한 기능에 대한 자리 표시 자로 사용했습니다. – itsadok