Araña web en python
Adrian Ferreres Esteller
raro82 en hotmail.com
Lun Abr 25 12:24:10 CEST 2005
Saludos lista:
Estoy intentando realizar una araña web muy sencilla en python pero me
da un error de socket que yo entiendo que se debe a que el socket, en algun
lado, se cierra antes de lo previsto. El error concreto es este:
socket.error: (9, 'Bad file descriptor')
Se da en la linea 65 y el codigo de la araña es el siguiente:
import socket
import sys
from string import split
from string import find
import os
import string
import re
def aranya_web (URL,num,socket,error=1):
mi_re = re.compile('href *= *"([^"]+)|href *= *([^ >]+)', re.IGNORECASE)
#Función que obtiene los links de una página web y devuelve una lista con
sus enlaces
def get_links(fn):
enlaces=[]
f = open(fn)
l = f.readline()
while l:
for link in mi_re.findall(l):
enlaces.append(string.join(link,''))
l = f.readline()
return enlaces
#Función devuelve una ruta en disco donde almacenar las páginas que la araña
se baja
def ruta_disco (URL):
if URL[1]=="":
archivo="index.htm"
directorio=URL[0]
else:
archivo=URL[len(URL)-1]
directorio=""
for i in xrange(1,len(URL)-1):
directorio=directorio+URL[i]+"/"
if not os.access (directorio,os.F_OK):
os.makedirs (directorio)
return directorio+archivo
#Funcion que obtiene la dirección URL definitava de la página web objetivo
def ruta_web (URL,socket):
if URL[1]=="":
direccion="/index.htm"
http_request="GET "+direccion+" HTTP/1.0\r\n\r\n"
if not socket.send (http_request):
return "/index.html"
else:
return direccion
else:
direccion=""
for i in xrange(1,len(URL)):
direccion=direccion+"/"+URL[i]
return direccion
#Funcion que, dado una dirección URL y una ruta en disco, graba una página
web en el archivo de dicha ruta
def pagina_web (file,direccion,socket):
f=open (file,'w')
http_request="GET "+direccion+" HTTP/1.0\r\n\r\n"
if not socket.send(http_request):
f.close()
return -1
linea=socket.recv (1024)
fin_cabecera=False
while linea:
if fin_cabecera:
f.write (linea)
else:
fin=find (linea,"\r\n\r\n")
if fin!=-1:
f.write(linea[fin+4:])
fin_cabecera=True
linea=socket.recv (1024)
socket.close()
f.close()
return 1
#De la URL original nos desacemos de la subcadena "http://"
URL= URL[7:]
#Transformamos la cadena URL en una lista donde cada uno de sus miembros son
las subcadenas que estaban separadas por '/'
URL= split (URL,'/')
#Obtenemos la ruta en disco donde guardar la página a bajarse
file= ruta_disco (URL)
#Obtenemos la direccion URL de la página
direccion=ruta_web (URL,socket)
#Nos descargamos la página al disco duro
resultado=pagina_web (file,direccion,socket)
if resultado==-1:
return -1
else:
lista_link=get_links (file)
#Si no hay mas links en la página acabamos
if len(lista_link)==0:
return 1
else:
#Si hay links en la página hacemos una llamada recursiva por cada link para
bajarnos las páginas. Num indica el maximo de llamadas recursivas permitidas
if num>0:
for i in xrange (len(lista_link)):
error=error*aranya_web (lista_link[i],num-
len(lista_link),socket)
return error
#Se pasa una direccion URL inicial
path= sys.argv[1]
URL= path[7:]
URL= split (URL,'/')
#Se conecta el socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect ((URL[0],80))
#Se descargan todas las páginas
resultado= aranya_web (path,20,s)
#Si el las descargas ha habido un error se comunica
if resutlado>0:
print "Recorrido de la web realizado con exito"
else:
print "se ha producido un error en la descarga de al menos una web"
s.close ()
¿Alguien me puede hechar luz sobre este asunto? Muchas gracias
Más información sobre la lista de distribución Python-es