Python - [Python] Duda con comparacion de cadenas en una lectura de socket

   
Vista:

[Python] Duda con comparacion de cadenas en una lectura de socket

Publicado por Principe_Azul (6 intervenciones) el 05/11/2013 07:48:44
Hola! Estoy aprendiendo programacion Python y he creado un bot para el IRC, solo dispone de 4 funciones, pero me hes útil por lo menos para empezar y entenderle un poco al lenguaje.
Mi duda es la siguiente:
¿Cómo puedo comparar códigos HTML en una lectura de sockets con algunas variables?
Es decir lo que quiero que mi bot haga es esto, por ejemplo pondre 12 lineas de código de ejemplo:

1
2
3
4
5
6
7
8
9
10
11
<div class="nota clearfix" id="notafinal">
<div class="volanta">PROYECTO APROBADO POR UNANIMIDAD EN EL CONCEJO DELIBERANTE DE LA CAPITAL</div>
<h2><a href="/notas/2013/10/30/proponen-ensenar-ninos-lengua-senas-487696.asp" >Proponen enseñar a los niños la lengua de señas</a></h2>
 
<div class="fotoNota" id="w300"><a href="/notas/2013/10/30/proponen-ensenar-ninos-lengua-senas-487696.asp" ><img
src="/fotografias/portada/300-171984.jpg" alt="Proponen enseñar a los niños la lengua de señas" width="300" border="0" /></a>
<p class="epigrafe">Los ediles tuvieron una rápida sesión y aprobaron todos los proyectos.</p>
</div>
		<div><p><span class="hora">30/10/2013 | </span>Se busca integrar a las personas sordomudas. Un desafío para los jardines de infantes.</p></div>
<div class="comentarios"><a href="/notas/2013/10/30/proponen-ensenar-ninos-lengua-senas-487696.asp#comentarios" >Dejá tu
comentario</a></div>

Lo que yo quiero es que mi bot extraiga informacion de una pagina web de noticias de mi provincia y la envíe al canal principal de la Red.
El código que hice para que el bot detecte el comando es este (voy a poner solo un pedazo de código):

1
2
if contexto.startswith('!noticias'):
    Web()

Entonces un usuario al ejecutar el comando !noticias el script llama a la función Web
Y el código de la función es así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def WebL():
    while 1:
        try:
            f = urllib2.urlopen("http://www.paginadenoticias.com.ar")
            print f.read()
            SantiagoNoticias = f.read()
            f.close()
            break
            if ' | </span>' in SantiagoNoticias:
                CuentaNoticias = CuentaNoticias + 1
                if 10 >= 5: #Esta linea es diferente, la puse asi para ver si puede funcionar el script
                    ContenidoNoticia1 = SantiagoNoticias
                    ContenidoNoticia2 = ContenidoNoticia1.find('</span>') + 7
                    InfoNoticia = ContenidoNoticia1[ContenidoNoticia2:ContenidoNoticia1.find('</p>')]
                    s.send('PRIVMSG #Argentina : 5 %s \r\n' % TituloNoticia)
                    s.send('PRIVMSG #Argentina : 2 %s \r\n' % InfoNoticia)
        except HTTPError, e:
            s.send('PRIVMSG #Argentina : Ha ocurrido un error en la conexion con la pagina web!')
            print e.code
        except URLError, e:
            s.send('PRIVMSG #Argentina : ERROR: La URL es incorrecta . . .')
            print e.reason
        except BaseException as err:
            exit()

Bueno creo que no es necesario pasar todo el código, además quiero hacer mi propio código y me estoy esforzando lo más que puedo para lograrlo, pero siempre necesitamos ayuda de alguien. Espero que sepan comprender.
Al ejecutar el programa, el bot entra al servidor, se loguea y todo bien, hasta incluso no cae obviamente no debe caer, osea me refiero a que responde los "PING's" del servidor cuando el mismo le envía.
Cuando un usuario ejecuta el comando !noticias el código llama a la función Web que ejecuta la tarea de abrir una página web, hasta ahí todo ok, luego veo en la consola todos los códigos de la página que por supuesto pasan demasiado rápido, pero logro ver el final del código, osea que abre bien la conexión y lee bien.
Pero el problema viene ahora, cuando intento comparar si la cadena | </span> esta dentro de la línea del código HTML que vendría a ser lo mismo que el "isin" de mIRC Scripting, osea si la cadena A se encuentra dentro de la cadena B.
Lo que quiero es que el código trate de guardar en una variable este valor por ejemplo:

1
<div><p><span class="hora">30/10/2013 | </span>Se busca integrar a las personas sordomudas. Un desafío para los jardines de infantes.</p></div>

Eso es una sola línea y por eso utilicé el ' | </span>' y sería si esa cadena esta (in) en la linea SantiagoNoticias de ser así que guarde en otra variable el contenido de esa cadena para poder quitarle los códigos HTML innecesarios y quedarme solo con la info, osea con la noticia, ejemplo:
" Se busca integrar a las personas sordomudas. Un desafío para los jardines de infantes. "
He probado poniendo un print "hola" para ver si en cada línea que me mostraba la consola de python aparecían esos "hola", pero sólo apareció al final. Algo así:

</html>
hola

Osea que jamás se va a poder comparar porque es como si fuera que la lectura del socket es de un tirón y se saltara el bucle.
He probado varias maneras pero no consigo hacer que se comparen esas cadenas, en realidad son varias (3), pero solo puse de ejemplo una.
Amigos yo solo quiero por ahora algo basico, osea que compare la información que va extrayendo de la web con una cierta cadena, eso nada más, no creo que sea necesario instalar alguna librería, creo que con las que trae Python es suficiente para lo que necesito, solo es una comparacion de cadenas de textos con códigos HTML.
Por favor espero que me ayuden, desde ya les agradezco.
Muchas gracias.
Buena suerte!! :)
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

[Python] Duda con comparacion de cadenas en una lectura de socket

Publicado por Principe_Azul (6 intervenciones) el 05/11/2013 07:58:02
Disculpen, me he equivocado al pegar el código en la parte esta:

def WebL():

Ahi me equivoque al postear, pero en mi código esta bien el nombre de la función, osea en mi código está así:

def Web():

Espero que me ayuden!!
Gracias!! : )
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de xve

[Python] Duda con comparacion de cadenas en una lectura de socket

Publicado por xve (1235 intervenciones) el 05/11/2013 10:39:12
Hola, no se muy bien la estructura de la pagina que quieres descargar, pero yo he hecho cosas similares, y he utilizado htmlparser (http://docs.python.org/2/library/htmlparser.html)... podrás obtener todo el código html en listas con el contenido de la pagina dependiendo de los tags, id's, etc...

Coméntanos si te sirve, ok?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

[Python] Duda con comparacion de cadenas en una lectura de socket

Publicado por Principe_Azul (6 intervenciones) el 06/11/2013 09:59:10
Hola xve! Muchas gracias por responder :)
En realidad lo que estoy buscando es saber como poder hacer comparación de una cadena de texto con una variable que contendría una línea de código HTML.
Voy a ser más explicativo para que se me entienda mejor :)
Yo tengo un código en Python que lo único que hace es conectar una Red IRC y tiene funciones que renococen solamente 3 comandos, osea por ejemplo el bot está en el canal #Argentina y yo al ejecutar !join #Ayuda el bot entraría al canal #Ayuda
También tiene un comando que es el !noticias, al ejecutar este comando el script y abre una conexión una página web y llama a la función LeeHTML(), lo que utilizo para eso es esto:

1
2
3
if contexto.startswith('!noticias'):
                    f = urllib2.urlopen("http://www.nuevodiarioweb.com.ar")
                    LeeHTML()

Entónces el bot abre una conexión con esa página web y va almacenando en una variable cada línea que va leyendo de la página web, hasta ahí todo me funciona bien, un ejemplo sería así:

1
2
datos = f.recv(1024)
print datos

El script recibe un máximo de 1024 kbs en el buffer y lo guarda en una variable de nombre "datos", luego yo puedo observar que en la consola de Python van a apareciendo todas las líneas HTML de esa página que abrí anteriormente y luego de leer toda la página, se cierra la conexión.
El problema me viene ahora porque lo que yo intento hacer es un bot de noticias que extraiga de esa página las noticias y los titulos de ellas.
Se que esto es complicado y que muchas personas no se pondrían en este trabajo ya que algún día la página puede cambiar su contenido y mi script ya no funcionará.
Pero de todas maneras intento hacerlo y espero que esa página cambie después de mucho tiempo.
Bien ahora haré una buena explicación de lo que intento hacer, voy a poner de ejemplo 9 líneas:

1
2
3
4
5
6
7
8
9
<div class="fotoNota" id="w380"><a href="/notas/2013/10/31/fuerte-tormenta-cayo-sobre-santiago-estero-488065.asp" ><img
src="/fotografias/portada/105582.jpg" alt="Una fuerte tormenta cayó sobre Santiago" width="380" border="0" ></a>
</div>
 
<div>
<p><span class="hora">22:24 | </span>Después de las 21 la Madre de Ciudades se vio afectada por un temporal de viento y lluvia, tal como estaba anunciado desde la mañana de hoy por el Servicio Meteorológico Nacional.</p>
</div>
<div class="comentarios"><a href="/notas/2013/10/31/fuerte-tormenta-cayo-sobre-santiago-estero-488065.asp#comentarios" >Dejá tu
comentario</a></div>

En este formato se muestran todas las noticias de la página y yo deseo extraer solo la información de la noticia para que quede así:

Después de las 21 la Madre de Ciudades se vio afectada por un temporal de viento y lluvia, tal como estaba anunciado desde la mañana de hoy por el Servicio Meteorológico Nacional.

Por eso es que yo utilicé esta cadena en un "if":

1
if ' | </span>' in SantiagoNoticias:

Al detectar esa cedena osea esta " | </span>" el script debe guardarla en otra variable osea así:

1
Noticia1 = SantiagoNoticias

Y sólo me quedaría quitarle las etiquetas HTML para que quede solo la noticia, lo mismo quiero hacer con los títulos.
Yo soy programador de mSL (mIRC Scripting Language) y al código lo hice sin problemas, me funciona bien, intento hacerlo en Python pero me falla en la parte de la comparación, es como que no encuentra lo que le estoy especificando o puede que esa comprobación no esté dentro del bucle.
Para que me puedan ayudar mucho mejor, voy a pegar el código que tengo actualmente de la función LeeHTML()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def LeeHTML():
    while 1:
        try:
            SantiagoNoticias = f.read()
            print SantiagoNoticias
            if '</html>' in SantiagoNoticias:
                s.send('PRIVMSG #Argentina : 5Si se ha encontrado el fina de la web\r\n')
                #f.close()
            if '<div class="fotoNota" id="w380">' in SantiagoNoticias:
                TituloNoticia1 = SantiagoNoticias
                TituloNoticia2 = TituloNoticia1.find('alt="')
                TituloNoticia = TituloNoticia1[TituloNoticia2:TituloNoticia1.find('" width="380"')]
            if '(<div class="volanta">' in SantiagoNoticias and len(TituloNoticia) == 0:
                TituloNoticia1 = SantiagoNoticias
                TituloNoticia2 = TituloNoticia1[TituloNoticia1.find('>')+1:]
                TituloNoticia = TituloNoticia2.replace('</div>', '')
                s.send('PRIVMSG #Argentina : 5Aqui esta el titulo: %s\r\n' % TituloNoticia)
            if ' | </span>' in SantiagoNoticias:
                ContenidoNoticia1 = SantiagoNoticias
                ContenidoNoticia2 = ContenidoNoticia1.find('</span>') + 7
                InfoNoticia = ContenidoNoticia1[ContenidoNoticia2:ContenidoNoticia1.find('</p>')]
                s.send('PRIVMSG #Argentina : 5 %s \r\n' % TituloNoticia)
                s.send('PRIVMSG #Argentina : 2 %s \r\n' % InfoNoticia)
            f.close()
            break
        except HTTPError, e:
            s.send('PRIVMSG #Argentina : Ha ocurrido un error en la conexion con la pagina web!')
            print e.code
        except URLError, e:
            s.send('PRIVMSG #Argentina : ERROR: La URL es incorrecta . . .')
            print e.reason
        except BaseException as err:
            exit()

Bueno pareciera ser que todo está bien, ustedes me dirán y me ayudarán a que pueda hacer mi bot de noticias. Yo sigo leyendo el tutorial de Python para todos.
Desde ya les agradezco muchísimo, gracias y que tengan un buen día :)

PD: He notado que el bot envía muchos "comandos desconocidos", los comandos son etiquetas de HTML, esto es solo una parte:

[':190.211.206.126 421 Bot_Noticias <a :Unknown command\r', ':190.211.206.126 42
1 Bot_Noticias <a :Unknown command\r', ':190.211.206.126 421 Bot_Noticias </div>
:Unknown command\r', ':190.211.206.126 421 Bot_Noticias <div :Unknown command\r
', ':190.211.206.126 421 Bot_Noticias <form :Unknown command\r',

Debe enviar como 40 comandos, osea tags de HTML, realmente no se porque sucede esto, seguire probando y buscando corregir el error.
Lo único que me devuelve el bot es esto:

[05:32] Bot_Noticias: Si se ha encontrado el fina de la web
[05:32] Bot_Noticias: alt="" name="" width="16" height="16" /></a>
[05:32] Bot_Noticias: <span id="max">Máx: °</span><span id="min">Min: °</span></div>

PD: He leído sobre esa librería, pero me encantaría y sería de mucha ayuda que me des algunos ejemplos simples para que pueda entender como trabaja esa librería. Te lo agradeceria mucho : )
Desde ya muchas gracias!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de xve

[Python] Duda con comparacion de cadenas en una lectura de socket

Publicado por xve (1235 intervenciones) el 06/11/2013 15:08:06
Muchas gracias por tu explicación... haber si te sirve algo así... este código lee el codigo html linea por linea en busca de la noticia, cuando la encuentra, muestra la noticia unicamente.

No se si te sirve, ya que solo miro por linea, si la noticia tuviera mas de una linea ya no funcionaria.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -*- coding: utf-8 -*-
 
html="""<div class="fotoNota" id="w380"><a href="/notas/2013/10/31/fuerte-tormenta-cayo-sobre-santiago-estero-488065.asp" ><img
src="/fotografias/portada/105582.jpg" alt="Una fuerte tormenta cayó sobre Santiago" width="380" border="0" ></a>
</div>
        
<div>
<p><span class="hora">22:24 | </span>Después de las 21 la Madre de Ciudades se vio afectada por un temporal de viento y lluvia, tal como estaba anunciado desde la mañana de hoy por el Servicio Meteorológico Nacional.</p>
</div>
<div class="comentarios"><a href="/notas/2013/10/31/fuerte-tormenta-cayo-sobre-santiago-estero-488065.asp#comentarios" >Dejá tu 
comentario</a></div>"""

for line in html.splitlines():
    if ' | </span>' in line:
        print line[37:-4]

Coméntanos, ok?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

[Python] Duda con comparacion de cadenas en una lectura de socket

Publicado por Principe_Azul (6 intervenciones) el 07/11/2013 10:19:14
Hola! Muchas gracias por tu gran ayuda, me ha servido el código :D :)
He solucionado el problema, ahora si guarda y envía las noticias como quería, pero ahora tengo un pequeño problema.
El bot trata de enviar las noticias al canal, pero cae por Exceso de flood porque debe enviar como 20 noticias y 20 titulos a la vez.
He probado diferentes métodos, pero no consigo que se incremente una variable, el código es este:

1
2
3
4
5
6
7
8
9
10
11
if ' | </span>' in linea:
                    CuentaNoticias = CuentaNoticias + 1
                    #inc() #Probé así también con esta función y no me funciona.
                    if CuentaNoticias <= 3:
                        ContenidoA = linea
                        ContenidoB = ContenidoA.find('</span>') + 7
                        InfoNoticia = ContenidoA[ContenidoB:ContenidoA.find('</p>')]
                        #s.send('PRIVMSG #Argentina : 5 %s \r\n' % TituloNoticia)
                        #s.send('PRIVMSG #Argentina : 2 %s \r\n' % InfoNoticia)
                        print TituloNoticia
                        print InfoNoticia

Por el momento lo dejo así como el "print" para poder ver la cantidad de noticias que el bot envía al canal, luego lo cambiaré.
Lo que yo deseo es que la variable CuentaNoticias vaya incrementando de a 1 y al llegar a 3 deje de enviar las noticias, osea que el bot enviaría 3 títulos y 3 noticias.
Pero el bot se desconecta del Servidor y se cierra la consola de Python y no envía las noticias.
Probé llamando a una función:

1
2
def inc():
    return CuentaNoticias+1

y también probé con esta otra:

1
2
def inc():
    CuentaNoticias = CuentaNoticias + 1

Pero las dos no me funcionan.
Te agradecería mucho que me ayudaras con este problemita que tengo ahora.
Desde ya te agradezco, has sido muy amable.
Buena suerte!! : )

PD: Estoy muy agradecido porque he solucionado el problema de la comparación de las cadenas gracias a vos.
Gracias hermano!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de xve

[Python] Duda con comparacion de cadenas en una lectura de socket

Publicado por xve (1235 intervenciones) el 07/11/2013 16:05:41
En las funciones no te funcionara, ya que ahí la variable CuentaNoticias no existe!!! es como si fuera una variable con otro nombre.
Recuerda que por defecto las variables únicamente viven dentro de sus funciones.

De la manera que lo tienes en el ejemplo, debería de funcionar-te...
Has probado ha hacer un print de la variable?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

[Python] Duda con comparacion de cadenas en una lectura de socket

Publicado por Principe_Azul (6 intervenciones) el 08/11/2013 07:57:18
Hola nuevamente! He terminado con éxito el código, el problema era el que vos me decías, la inicialización de la variable y por eso se cerraba la consola, en el código anterior que postee era ese código el que tenía problemas, simplemente porque la variable no existía y el programa no podía sumar un número a una vacía.
A la variable la había puesto en esta parte:

1
2
3
4
if contexto.startswith('!noticias'):
                    CuentaNoticias = 0
                    f = urllib2.urlopen(http://www.paginadenoticias.com.ar)
                    LeeHTML()

y también había probado poniéndola a la variable aquí:

1
2
3
4
var1 = contenido1
var2 = contenido2
CuentaNoticias = 0
var3 = contenido3

osea las variables no estaban en ningún lado y por eso no existía.
Yo pensaba que en Python las variables eran como fijas/globales y se mantenían en memoria a menos que la dejes nula, pero estas variables trabajan exactamente igual que las variables locales de mIRC, sólo funcionan cuando están dentro de funciones/bucles/condicionales etc.
Hace como 2 semanas que estoy aprendiendo python y ya he podido hacer un bot de noticias gracias a tu ayuda y a una persona que también me ayudó en otro foro.
xve te agradezco enormemente por tu explicación y ayuda, muchas gracias!!

Al comienzo de crear mis addons para mIRC hacía mucho eso, bucles infinitos y bueno nunca entendía porque tenía que haber un incremento en la variable, hasta que lo entendí, les doy un consejo a los usuarios de este foro:
Si desean aprender a programar y son novatos como yo en el caso de Python, les recomendaría aprender mIRC Scripting, la verdad me ha ayudado demasiado porque con Batch no iba a poder hacer jamás las cosas que hice en mIRC, Batch es un programa de procesamiento por lotes y trabaja con las rutinas diarias de la pc, mIRC es mucho más amplio y su programación puede ir más alla de lo que es el IRC.
Por supuesto que este consejo es si nunca en la vida programaron, es un consejo de corazón y de la mejor onda!! :)

Bueno pueden cerrar el post, problema solucionado.
Vuelvo a darte las gracias xve has sido muy amable y educado, me has ayudado y me has explicado varios conceptos, te agradezco.
Buena suerte para todos y que tengan un buen día!!!!! :)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar