2012-10-15 3 views
3

현재 테이블을 배열로 파싱하려고 할 때 약간의 문제가 있습니다.아름다운 스프, html 테이블 파싱

나는 BS4를 구문 분석하고 셀 내용을 배열에 넣는 데 필요한 간단한 테이블 (HERE)을 가지고 있습니다. 여기에서 일을 어렵게 만드는 것은 세포가 텍스트를 포함하지 않고 오히려 다음 제목을 가진 이미지를 가지고 있다는 사실입니다. "확인"또는 "사이트"- 이것은 사용자 권한 일뿐입니다.

위의 바이올린을 보면 [체크 박스를 포함 나는 생략하고 행 하나, 사람들은 내가 문제없이 추출 할 수 있습니다, 내가 오직 할 필요가있는 그런 방법으로 결과 배열이 점에서 구문 분석하는 것입니다 다음과 같이됩니다 :

Array1[0] = User1,Confirm,Confirm,Site,Confirm 
Array1[1] = User2,Confirm,Confirm,Confirm,Confirm 
Array1[2] = User3,Confirm,Confirm,Confirm,Confirm 
Array1[3] = User4,Confirm,Site,Site,Confirm 

나는 그 다음에 내가 할 수있는대로 할 수있다. 또 다른 문제는 행 수가 달라져서 스크립트가 이에 적응할 수 있어야하고 재귀 적으로 테이블에서 배열을 생성 할 수 있어야한다는 것입니다.

현재 StackOverflow가 유일한 유일한 희망입니다. 지난 10 시간 동안 나 자신을 거의 성공하지 못했지만 솔직하게 나는 희망을 잃었습니다. 가장 가까운 항목을 얻으려는 시도는 묶인 태그를 추출하는 것이었지만 일부 이상한 이유로 구문 분석 할 수 없었습니다. 아마도 bs4의 중첩 제한 사항일까요? 누구든지 좀 봐 주시겠습니까? 그리고이 일을하는 방법을 찾을 수 있는지 보시겠습니까? 또는 적어도 거기에 도착하는 방법을 설명하십시오?

var 설명 : rightml - 테이블 용 수프.

allusers = [] 
rows = rightml.findAll('tr') 
for tr in rows: 
    cols = tr.findAll('td') 
    for td in cols: 
     if (td.find(title="Group")) or (td.find(title="User")): 
      text = ''.join(td.text.strip()) 
      allusers.append(text) 
print allusers 

gifrights = [] 

rows7 = rightml.findAll('td') 
#print rows7 
for tr7 in rows: 
    cols7 = tr7.findAll('img') 
    for td7 in cols7: 
     if (td7.find(title="Confirm")) or (td7.find(title="Site")): 
      text = ''.join(td7.text.strip()) 
      text2 = text.split(' ') 
      print text2 
      gifrights.append(text2) 

이 코드로 WAY 해제 될 수있다 ..하지만 난 그것을 팔자 '대학 시도를했다. 이 작품 같은

답변

5

겠습니까 뭔가 :

[u'Logged-in users', u'True', u'True', u'True', u'True'] 
[u'User 1', u'Confirm', u'Confirm', u'Site', u'Confirm'] 
[u'User 2', u'Confirm', u'Confirm', u'Confirm', u'Confirm'] 
[u'User 3', u'Confirm', u'Confirm', u'Confirm', u'Confirm'] 
[u'User 4', u'Confirm', u'Site', u'Site', u'Confirm'] 
+0

는 확인합니다. 그러나 이것이 작동한다면, 당신은 모든 인터넷을 가질 수 있습니다! – Meh

+0

은 매우 잘 작동합니다. 고맙습니다! – Meh

4

내가 같은 행에 걸쳐 지능형리스트를 사용하는 빠른 생각 :

rows = soup.find('tbody').findAll('tr') 

for row in rows: 
    cells = row.findAll('td') 

    output = [] 

    for i, cell in enumerate(cells): 
     if i == 0: 
      output.append(cell.text.strip()) 
     elif cell.find('img'): 
      output.append(cell.find('img')['title']) 
     elif cell.find('input'): 
      output.append(cell.find('input')['value']) 
    print output 

이 다음과 같은 출력합니다. 사용자 # 때문에, 당신은 정말 사용자 번호가 필요하지 않습니다

# superpythonic 
[[j['title'] for j in i.findAll('img')] for i in rows[1:]] 

# all together now, but not so pythonic 
[[j['title'] for j in i.findAll('img')] for i in soup.find('tbody').findAll('tr')[1:]] 

: 당신

['User', 'Confirm', 'Confirm', 'Site', 'Confirm'] 
['User', 'Confirm', 'Confirm', 'Confirm', 'Confirm'] 
['User', 'Confirm', 'Confirm', 'Confirm', 'Confirm'] 
['User', 'Confirm', 'Site', 'Site', 'Confirm'] 
당신은 중첩 된 지능형리스트를 사용하여 더 많은 단계를 줄일 수

을 제공

rows = soup.find('tbody').findAll('tr') 

for i in rows[1:]: # the first row is thrown out 
    [j['title'] for j in i.findAll('img')] 

인덱스 번호 + 1입니다.

[[j['title'] for j in i.findAll('img') if j['title'] != 'User'] for i in rows[1:]] 

그러나, 당신이 하나가 -must- 경우 ...

for i in xrange(len(users)): 
    users[i].append("User " + str(i+1)) 

, 당신이 일을 주장한다면, 나는 데이터 구조 대신 목록으로 namedtuple을 사용합니다.내가 집으로 생각하면 namedtuple

from collections import namedtuple 
# make these actual non-obfuscated names, not column numbers 
User = namedtuple('User', ('num col_1 col_2 col_3 col_4') 

그리고 당신은 user으로 사용자 1, 말, 대한 namedtuple의 인스턴스를 일단 다음, 당신이 할 수있는 ...

>>> user.num 
... 1 
>>> user.col_1 
... 'Confirm' 
>>> user.col_2 
... 'Confirm' 
>>> user.col_3 
... 'Site' 
>>> user.col_4 
... 'Confirm' 
+0

위의 방법뿐만 아니라이 방법을 사용해 보았습니다. 둘 다 잘 작동합니다. 설명과 제안에 많은 감사드립니다! – Meh

관련 문제