2014-04-30 16 views
30

Uczę się Pythona requests i BeautifulSoup. Do ćwiczenia wybrałem napisanie szybkiego parsera biletów parkingowych NYC. Jestem w stanie uzyskać odpowiedź html, która jest dość brzydka. Muszę pobrać lineItemsTable i przeanalizować wszystkie bilety.python BeautifulSoup parsing table

można odtworzyć stronę wchodząc tutaj: https://paydirect.link2gov.com/NYCParking-Plate/ItemSearch i wprowadzając NY płytę T630134C

soup = BeautifulSoup(plateRequest.text) 
#print(soup.prettify()) 
#print soup.find_all('tr') 

table = soup.find("table", { "class" : "lineItemsTable" }) 
for row in table.findAll("tr"): 
    cells = row.findAll("td") 
    print cells 

Czy ktoś mógłby mi pomóc? Prosty wygląd dla wszystkich tr nigdzie mnie nie zaprowadzi.

+0

Przy bliższej lekturze, nie jestem właściwie pewien, jakie jest twoje pytanie. Czy możesz dokładnie wyjaśnić, z której części potrzebujesz pomocy? – TML

Odpowiedz

71

tu proszę:

data = [] 
table = soup.find('table', attrs={'class':'lineItemsTable'}) 
table_body = table.find('tbody') 

rows = table_body.find_all('tr') 
for row in rows: 
    cols = row.find_all('td') 
    cols = [ele.text.strip() for ele in cols] 
    data.append([ele for ele in cols if ele]) # Get rid of empty values 

To daje:

[ [u'1359711259', u'SRF', u'08/05/2013', u'5310 4 AVE', u'K', u'19', u'125.00', u'$'], 
    [u'7086775850', u'PAS', u'12/14/2013', u'3908 6th Ave', u'K', u'40', u'125.00', u'$'], 
    [u'7355010165', u'OMT', u'12/14/2013', u'3908 6th Ave', u'K', u'40', u'145.00', u'$'], 
    [u'4002488755', u'OMT', u'02/12/2014', u'NB 1ST AVE @ E 23RD ST', u'5', u'115.00', u'$'], 
    [u'7913806837', u'OMT', u'03/03/2014', u'5015 4th Ave', u'K', u'46', u'115.00', u'$'], 
    [u'5080015366', u'OMT', u'03/10/2014', u'EB 65TH ST @ 16TH AV E', u'7', u'50.00', u'$'], 
    [u'7208770670', u'OMT', u'04/08/2014', u'333 15th St', u'K', u'70', u'65.00', u'$'], 
    [u'$0.00\n\n\nPayment Amount:'] 
] 

kilka rzeczy do uwaga:

  • Ostatni wiersz na powyższym wyjściu, Kwota płatności nie jest częścią tabeli, ale w ten sposób określa się tabelę. Możesz go odfiltrować przez sprawdzenie, czy długość listy jest mniejsza niż 7.
  • Ostatnia kolumna każdego wiersza będzie musiała być obsługiwana osobno, ponieważ jest to wejściowe pole tekstowe.
+3

Zastanawiam się, dlaczego to działa dla Ciebie ... Otrzymuję 'rows = table_body.find_all ('tr') AttributeError: Obiekt" NoneType "nie ma atrybutu" find_all'' – Cmag

+0

@Cmag Czy używasz Beautiful Soup 4? – shaktimaan

+0

od importu bs4 BeautifulSoup – Cmag

14

rozwiązany, to w jaki sposób parse ich wyniki html:

table = soup.find("table", { "class" : "lineItemsTable" }) 
for row in table.findAll("tr"): 
    cells = row.findAll("td") 
    if len(cells) == 9: 
     summons = cells[1].find(text=True) 
     plateType = cells[2].find(text=True) 
     vDate = cells[3].find(text=True) 
     location = cells[4].find(text=True) 
     borough = cells[5].find(text=True) 
     vCode = cells[6].find(text=True) 
     amount = cells[7].find(text=True) 
     print amount