2011-02-09 2 views
0

클래스에 대한 데이터 스크래핑 파일을 만들려고하고 있습니다. 데이터를 스크래핑하려면 while 루프를 사용하여 올바른 데이터를 별도의 배열로 가져와야합니다. 나는 동안 루프를 설정하면 상태 및 SAT 평균은 등특성 목록에서 생성 된 문자열에 대한 특성 오류입니다.

그러나, 데이터에서 html 태그의 대부분을 지워 내 정규식 파산, 난라는 오류가 무엇입니까 :

Attribute Error: 'NoneType' object has no attribute 'groups'

내 코드는 다음과 같습니다

import re, util 
from BeautifulSoup import BeautifulStoneSoup 

# create a comma-delineated file 
delim = ", " 

#base url for sat data 
base = "http://www.usatoday.com/news/education/2007-08-28-sat-table_N.htm" 

#get webpage object for site 
soup = util.mysoupopen(base) 

#get column headings 
colCols = soup.findAll("td", {"class":"vaTextBold"}) 

#get data 
dataCols = soup.findAll("td", {"class":"vaText"}) 

#append data to cols 
for i in range(len(dataCols)): 
    colCols.append(dataCols[i]) 

#open a csv file to write the data to 
fob=open("sat.csv", 'a') 

#initiate the 5 arrays 
states = [] 
participate = [] 
math = [] 
read = [] 
write = [] 

#split into 5 lists for each row 
for i in range(len(colCols)): 
    if i%5 == 0: 
     states.append(colCols[i]) 
i=1 
while i<=250: 
    participate.append(colCols[i]) 
    i = i+5 

i=2 
while i<=250: 
    math.append(colCols[i]) 
    i = i+5 

i=3 
while i<=250: 
    read.append(colCols[i]) 
    i = i+5 

i=4 
while i<=250: 
    write.append(colCols[i]) 
    i = i+5 

#write data to the file 
for i in range(len(states)): 
    states = str(states[i]) 
    participate = str(participate[i]) 
    math = str(math[i]) 
    read = str(read[i]) 
    write = str(write[i]) 

    #regex to remove html from data scraped 

    #remove <td> tags 
    line = re.search(">(.*)<", states).groups()[0] + delim + re.search(">(.*)<",  participate).groups()[0]+ delim + re.search(">(.*)<", math).groups()[0] + delim + re.search(">(.*)<", read).groups()[0] + delim + re.search(">(.*)<", write).groups()[0] 

    #append data point to the file 
    fob.write(line) 

이 오류가 갑자기 나타난 이유에 대한 아이디어가 있습니까? 내가 다른 목록으로 데이터를 분할하려고 할 때까지 정규 표현식이 잘 작동했다. 나는 이미 "for"루프 내에서 다양한 문자열을 인쇄하여 첫 번째 값 (0)에 대해 "없음"이 있는지를 확인했지만 그 문자열이 모두 있어야합니다.

도움이 될 것입니다.

답변

1

정규 표현식 검색에서 문자열 중 하나가 실패한 것으로 보이므로 MatchObject 대신 None을 반환합니다. 당신의 정규식이 실패하는 경우

out_list = [] 
for item in (states, participate, math, read, write): 
    try: 
     out_list.append(re.search(">(.*)<", item).groups()[0]) 
    except AttributeError: 
     print "Regex match failed on", item 
     sys.exit() 
line = delim.join(out_list) 

그런 식으로, 당신이 밖으로 찾을 수 있습니다

는 대신 매우 긴 #remove <td> tags 라인의 다음보십시오.

또한 .groups()[0] 대신 .group(1)을 사용하는 것이 좋습니다. 전자는 더 명백하다.