python parsanje

Pozdravljeni.
Imam problem sparsati url urnika v seznam kjer bi bilo za vsak dan od ponedeljka do petka za posamezno uro napisano ali je tisto uro kaj na urniku ali ne.
Začela sem nekako takole:
from bs4 import BeautifulSoup
import urllib.request

stran=urllib.request.urlopen('http://www-lp.fmf.uni-lj.si/urnik/urnikhtm.exe?Izbira=Ucilnica&ucilnica=2.01')
tekst=stran.read()
seznam=[]
soup = BeautifulSoup(tekst)

table = soup.find('table')
for col in table.find_all('td'):
seznam.append(col)

print(seznam)

Vendar nevem kako naj nadaljujem. Prosim za pomoč. LP

8 odgovorov

koda strani je pa nekaj takega :
<HTML>
<HEAD>
<TITLE>Zimski semester 2013/14 (Oddelek za matematiko FMF) (verzija 9. 12. 2013)</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-2">
</HEAD>
<BODY BGCOLOR=Silver>
<font color=Red>
<CENTER><H3>Zimski semester 2013/14 (Oddelek za matematiko FMF) (verzija 9. 12. 2013)</H3></CENTER></p>
<font color=Black>
<CENTER><H3>Predavatelj: Plestenjak</H3></CENTER></p>
<TABLE BORDER BGCOLOR=Silver BORDERCOLOR=Black COLS=6>
<TR> <TD> </TD> <TD BGCOLOR=AQUA COLSPAN=1><H3>PONEDELJEK</H3></TD> <TD BGCOLOR=AQUA COLSPAN=1><H3>TOREK</H3></TD> <TD BGCOLOR=AQUA COLSPAN=1><H3>SREDA</H3></TD> <TD BGCOLOR=AQUA COLSPAN=1><H3>ČETRTEK</H3></TD> <TD BGCOLOR=AQUA COLSPAN=1><H3>PETEK</H3></TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>7-8</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>8-9</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>9-10</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>10-11</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD NOWRAP ALIGN=CENTER BGCOLOR="#00FFFF" COLSPAN=1 ROWSPAN=2><SMALL><B>NA SEM</B><BR><I><A HREF=http://www.fmf.uni-lj.si/si/imenik/3357/>Plestenjak</A></I> 3.06</SMALL></TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD NOWRAP ALIGN=CENTER BGCOLOR="#00FFFF" COLSPAN=1 ROWSPAN=2><SMALL><B>NM 1 (F)</B><BR><I><A HREF=http://www.fmf.uni-lj.si/si/imenik/3357/>Plestenjak</A></I> 2.04</SMALL></TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>11-12</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>12-13</TD> <TD NOWRAP ALIGN=CENTER BGCOLOR="#00FFFF" COLSPAN=1 ROWSPAN=2><SMALL><B>INMLA+IPN</B><BR><I><A HREF=http://www.fmf.uni-lj.si/si/imenik/3357/>Plestenjak</A></I> 3.07</SMALL></TD> <TD NOWRAP ALIGN=CENTER BGCOLOR="#00FFFF" COLSPAN=1 ROWSPAN=2><SMALL><B>UNM</B><BR><I><A HREF=http://www.fmf.uni-lj.si/si/imenik/3357/>Plestenjak</A></I> 2.04</SMALL></TD> <TD NOWRAP ALIGN=CENTER BGCOLOR="#00FFFF" COLSPAN=1 ROWSPAN=3><SMALL><B>SEJA (PLESTENJAK)</B><BR><I><A HREF=http://www.fmf.uni-lj.si/si/imenik/3357/>Plestenjak</A></I> (2.02)</SMALL></TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD NOWRAP ALIGN=CENTER BGCOLOR="#00FFFF" COLSPAN=1 ROWSPAN=1><SMALL><B>UNM</B><BR><I><A HREF=http://www.fmf.uni-lj.si/si/imenik/3357/>Plestenjak</A></I> 2.05</SMALL></TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>13-14</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>14-15</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>15-16</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>16-17</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>17-18</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>18-19</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> </TR>
<TD BGCOLOR=AQUA ALIGN=CENTER><BR>19-20</TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> <TD BGCOLOR=Silver COLSPAN=1><PRE> </PRE> </TD> </TR>
</TABLE>
<p><hr><h4>Bor Plestenjak, IMFM 1997</h4></p>
<h4><A HREF=mailto:grega.cigler@fmf.uni-lj.si>Komentarji</A></h4>
</BODY>
</HTML>

Malo več logike je...osebno bi rešil drugače

  1. naredil bi dictionary, ki bi hranil dan-ura za ključ in True/False za vrednost
  2. Potem kot si že sam naredil, greš skozi vse "td"je, kjer gledaš če vsebuje bgcolor == #00FFFF (lahko tudi kaj drugega), torej da je ura zasedena
  3. potem za vsak dan greš td po td in rowspan, če je 1 ali ga ni, potem ta predmet zaseda samo 1 uro, če je več, zaseda več ur in pomeni da v ustvarjenem dictionaryju nastaviš več mest na True
  4. Ko greš skozi, potem samo gledaš dan-ura, ki ti pove če je zasedeno ali ne

Upam da je jasno, če ne pa spišemo kodo..

ali lahko prosim kodo, kr meni ne gre , pa noče mi it čez celo tabelo in nevem zakaj ne...

Jaz bi enostavno uporabil html parser knjižnico ali nekaj podobnega
http://docs.python.org/2/library/htmlparser.html

Hvala, vendar bi raje z bs4, saj se html parser zaradi opustitve ne uporablja več toliko. To s slovarji je zelo dobra ideja, vendar ne vem čisto točno kako napisati kodo. Ali lahko kdo pomaga...

To je dokaj splosen problem (da moras gledat rowspan in colspan)
pri parsanju HTML tabel.

Anyway kot prvo, ne mores poloopat po vseh TRjih ker je HTML broken. Nimas <TR>, razen prvega. To lahko sama uredis. Npr. odpres svoj HTML v crome in v inspectorju skopiras source ali pa kako automatiziras ta postopek.

Kodo & popravljen HTML pa imas tukaj:
https://gist.github.com/mkramb/8795572

lp

Hvala ti. Zanima me še kako se koda spremeni če spremenim html kodo takole in uporabim bs4.
url = 'http://www-lp.fmf.uni-lj.si/urnik/urnikhtm.exe?Izbira=Letnik&letnik=2.+letnik+(prakti%E8na+matematika)'
urlRead = urllib.request.urlopen(url)
html = urlRead.read()
html1 = html.decode("ISO-8859-2")
html2=html1.replace("</TR>","</TR><TR>")

    soup = BeautifulSoup(html2)

Lahko samo uporabis lxml podporo za BeautifulSoup
http://lxml.de/elementsoup.html

Nevem zakaj vztrajas pri Soup samo drugace pa poglej dokumentacijo (nima xpath tako da moras ta dela narediti "rocno").

Mimogrede lxml je hitrejski od BS.
Tega dela pa ti ne spisem ker mi ni interesantno :P