[Jsign-commits] CVS: pyweb getlinks.py,NONE,1.1
Brought to you by:
borillo
|
From: David R. <vr...@us...> - 2001-09-27 12:39:14
|
Update of /cvsroot/jsign/pyweb
In directory usw-pr-cvs1:/tmp/cvs-serv28430
Added Files:
getlinks.py
Log Message:
Esta es la nueva version del programa para extraer todos los links a partir de una determinada
dirección web. Ha mejorado muchísimo con respecto a su primera versión, ya que hace uso del modulo
urlparse (por qué no lo encontraría yo antes?). Echale un vistazo y verás que simple se ha quedado
ahora. Le faltan 2 cosas, reconocer las páginas que sean de error 404 o las que requieran autorización
401, para descartarlas. No sé como se podría hacer.
--- NEW FILE: getlinks.py ---
from sgmllib import *
import urllib, sys, re, string, urlparse
# Expresion regular que define la base de una URL
re_url = re.compile(r"^\s*(https?|ftp|gopher)://([a-zA-Z][a-zA-Z0-9_\-]+(\.[a-zA-Z][a-zA-Z0-9_\-]+)*|([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3}))")
# Ficheros donde registraremos los enlaces
logs = { "excludes" : "sic.excludes",
"links" : "sic.links",
"log" : "sic.log",
"extensions" : "sic.extensions",
"error" : "sic.error"
}
def cleanlink(link):
i = string.find(link, '#')
if i >= 0:
link = link[:i] # Remove #fragment
words = string.split(link) # Split in whitespace delimited words return
link = string.join(words, "")
return link
# Clase que se encarga de extraer las direcciones
class URLExtractor(SGMLParser):
def __init__( self , base ):
SGMLParser.__init__(self)
self.base = []
self.base.append(base) # Direccion base de descarga
self.actual='' # Direccion que estamos procesando actualmente
# Vaciamos los ficheros de log
for fichero in logs.keys():
open(logs[fichero], "w")
self.dic_urls = {} # Diccionario en el que se almacenan las ULRs visitadas y por visitar
self.noDownload = ['.pdf','.rtf','.hqx','.jpg','.gif','.jsp','.txt','.zip','.jar','.exe'] # Extensiones a no seguir
self.Download = ['.htm','.html','.thtml','.php','.pl'] # Extensiones a seguir
self.noValidURL = ['ftp','gopher']
self.noValidTAGS = ['mailto','javascript','news']
def start_a(self, attr):
# Buscamos dentro de los atributos del tag <a ...., el href
href = [ v for k,v in attr if k=='href' ]
for t in href:
# Añadimos la entrada en el log
open(logs["log"],"a+").write("Procesando el tag %s\n" % (t))
# Aqui hacemos magia. "link" será el links absoluto que queremos
link = urlparse.urljoin(self.actual, t)
if re_url.match(link) and re_url.match(link).group() in self.base:
link = cleanlink(link) # Eliminamos los # y los espacios
ruta = urlparse.urlparse(link)[2]
elem = string.split(ruta, "/")[-1]
i = string.find(elem, ".")
if i>=0:
extension = elem[i:]
if not extension in self.Download:
open(logs["excludes"], "a+").write("Enlace %s excluido de la dirección %s\n"%(link, self.actual))
return
else:
open(logs["excludes"], "a+").write("Enlace %s excluido de la dirección %s\n"%(link, self.actual))
return
# Si la URL aun no habia sido procesada y es de las que quiero procesar,
if not self.dic_urls.has_key(link):
self.dic_urls[link] = 0
open(logs["links"],"a+").write("%s\n" % (link))
# Quedan URLs por procesar ?
def has_urls(self):
return 0 in self.dic_urls.values()
# Dame una URL que no este procesada
def get_url(self):
return self.dic_urls.keys()[self.dic_urls.values().index(0)]
# Marca una URL como procesada
def use_url(self,u):
self.dic_urls[u] = 1
# Resetea el parser
def reset(self):
SGMLParser.reset(self)
def base_add(self, alias):
self.base.append(alias)
# Inicio del script
if __name__ == "__main__":
if len(sys.argv) < 2 or len(sys.argv)>1 and sys.argv[1] == "--help":
print ("Modo de uso: %s <URL de inicio> [<Dominio Alternativo>]" % (sys.argv[0]))
sys.exit()
if not re_url.match(sys.argv[1]):
print "Dirección incorrecta en el primer parámetro."
sys.exit()
else:
dir_base = re_url.match(sys.argv[1]).group()
if len(sys.argv) == 3:
if not re_url.match(sys.argv[2]):
print "Dirección incorrecta en el segundo parámetro."
sys.exit()
else:
dir_alias = re_url.match(sys.argv[2]).group()
parser = URLExtractor(dir_base)
parser.base_add(dir_alias)
else:
parser = URLExtractor(dir_base)
# Empezamos por la direccion que nos pasan como parámetro
parser.dic_urls[sys.argv[1]] = 0
url = parser.get_url()
print "URL:",url
count = 1
while url:
parser.actual=url
open(logs["log"], "a+").write("**********************************************\nDirección: %s\n\n" %(url))
print ( "%d. Procesando %s..." % (count, url))
try:
parser.feed(urllib.urlopen(url).read()) # Lanzo el parser ...
parser.close() # ... y lo cierro
except:
open(logs["error"], "a+").write("**********************************************\nDirección: %s\n\n" %(url))
parser.use_url(url) # Marco la URL como procesada
if parser.has_urls():
url = parser.get_url() # Obtengo una URL no procesada
parser.reset()
count = count + 1
else:
url = None
|