Created
August 31, 2011 11:09
-
-
Save jdelacueva/1183312 to your computer and use it in GitHub Desktop.
Extracción de datos de los senadores de la novena legislatura
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
""" | |
Copyright: Javier de la Cueva | |
Licencia: Affero GPL V3 | |
Script para generar un archivo csv con datos de los senadores de la | |
novena legislatura. | |
Uso: | |
---- | |
Ejecute en una línea de comandos: | |
$ python senadores_novena.py | |
Encontrará el archivo generado mediante dicha orden en el mismo | |
directorio que el script. | |
""" | |
import os | |
import csv | |
import re | |
import urllib2 | |
from datetime import date | |
from lxml.html import parse | |
cwd = os.getcwd() | |
join = os.path.join | |
root_path = os.path.dirname(cwd) | |
fecha_hoy = date.today().strftime('%Y-%m-%d') | |
# Constantes | |
# ---------- | |
# Si se desea, cambiar acorde con los directorios donde se almacenen los datos | |
outfile = join(root_path, '%s_senadores_novena_legislatura.csv' % fecha_hoy) | |
# Si se desea, cambiar según la legislatura cuyos datos se desean extraer | |
url = 'http://www.senado.es/solotexto/legis9/senadores/alfabet.html' | |
# Constantes correspondientes a la información a generar | |
nombre_parlamento = 'Senado' | |
jurisdiccion = 'Estado' | |
legislatura = 'Legislatura IX' | |
# Funciones | |
# --------- | |
# | |
# Hay 4 funciones: | |
# | |
# 1. def get_tree(url): | |
# | |
# Descarga una página web y genera su árbol. | |
# | |
# 2. get_urls_senadores(url): | |
# | |
# Construye una lista con todas las páginas públicas de los | |
# senadores. | |
# | |
# 3. extraer_datos(url): | |
# | |
# Extrae los datos relevantes de la página pública de un senador y | |
# construye un diccionario con ellos. | |
# | |
# 4 crear_csv(urls, outfile): | |
# | |
# Crea un archivo de valores separados por comas con el diccionario | |
# obtenido mediante la función `extraer_datos(url)`. Toma como | |
# parámetros la lista de urls públicas de los senadores y el nombre | |
# del archivo que se genera. | |
# | |
def get_tree(url): | |
""" | |
Descarga y genera el árbol de una página web. La conexión mostrará | |
cabeceras User-agent Mozilla/5.0 por ser necesarias para ser aceptada | |
por determinados servidores web. | |
Uso:: | |
>>> homepage = get_tree('http://www.senado.es') | |
""" | |
# TODO: Crear excepción si no hay conexión. | |
opener = urllib2.build_opener() | |
opener.addheaders = [('User-agent', 'Mozilla/5.0')] | |
sock = opener.open(url) | |
tree = parse(sock).getroot() | |
sock.close() | |
return tree | |
def get_urls_senadores(url): | |
""" | |
Crea una lista de urls de los senadores de la novena legislatura. | |
Toma como parámetro la url base donde se halla la lista de todos | |
los senadores de dicha legislatura, extrae las urls | |
correspondientes a la página pública de cada senador y crea una | |
lista con las urls extraídas. | |
""" | |
lista_urls = list() | |
tree = get_tree(url) | |
seleccion = tree.xpath('//li') | |
prefijo = 'http://www.senado.es/solotexto/legis9/senadores/' | |
for item in seleccion: | |
url = prefijo + item.getchildren()[0].attrib['href'] | |
lista_urls.append(url) | |
return lista_urls | |
def extraer_datos(url): | |
""" | |
Extrae los datos relevantes de la página pública de un senador. | |
Toma como parámetro la url de la página pública. | |
""" | |
tree = get_tree(url) | |
# Nombre y apellidos | |
nombre_apellidos = tree.xpath('//b')[0].text.encode('utf-8') | |
nombre = nombre_apellidos.split(',')[1].strip() | |
apellido_1 = nombre_apellidos.split(',')[0].strip() | |
apellido_2 = "" | |
# Fecha inicio y fin | |
fecha_inicio = tree.xpath('//li')[0].text_content().split(u' desde el día ')[1].strip('.') | |
fecha_fin = "" | |
# Legislatura, nombre parlamento, jurisdiccion: son constantes | |
# definidas más arriba. | |
# Nombre y tipo de circunscripción | |
nombre_circunscripcion = tree.xpath('//li')[0].text_content().split(u' desde el día ')[0].split(' por ')[1].encode('utf-8') | |
tipo_circunscripcion = "" # TODO: provincia, comunidad autónoma, isla. | |
# Partido político y grupo parlamentario | |
seleccion = tree.xpath('/html/body/blockquote/ul/li') | |
for item in seleccion: | |
if item.text == u'Partido Político: ': | |
partido_politico = item.text_content().split(':')[1].strip().title().encode('utf-8') | |
break | |
else: | |
partido_politico = "Desconocido" | |
try: | |
grupo_parlamentario = tree.xpath('//li//a')[1].text.strip().encode('utf-8') | |
except AttributeError: | |
grupo_parlamentario = tree.xpath('//li//a')[2].text.strip().encode('utf-8') | |
if tree.xpath('//a')[0].text_content() == '[correo]': | |
email = tree.xpath('//a')[0].attrib['href'].split(':')[1] | |
else: | |
email = "Sin datos" | |
return {'id_parlamentario': "", | |
'nombre_apellidos': nombre_apellidos, | |
'nombre': nombre, | |
'apellido_1': apellido_1, | |
'apellido_2': apellido_2, | |
'fecha_inicio': fecha_inicio, | |
'fecha_fin': fecha_fin, | |
'legislatura': legislatura, | |
'nombre_parlamento': nombre_parlamento, | |
'jurisdiccion': jurisdiccion, | |
'nombre_circunscripcion': nombre_circunscripcion, | |
'tipo_circunscripcion': tipo_circunscripcion, | |
'partido_politico': partido_politico, | |
'grupo_parlamentario': grupo_parlamentario, | |
'url': url, | |
'email': email | |
} | |
def crear_csv(urls, outfile): | |
""" | |
Crea un archivo de valores separados por comas con las cabeceras y | |
los datos por diputado. | |
Toma como parámetros la lista de urls de las páginas públicas de | |
los senadores y el nombre del archivo que se desea generar. | |
""" | |
out = csv.writer(open(outfile,"w"), delimiter=',', quoting=csv.QUOTE_ALL) | |
cabeceras = ['id_parlamentario', 'nombre_apellidos', 'nombre', 'apellido_1', | |
'apellido_2', 'fecha_inicio', 'fecha_fin', 'legislatura', | |
'nombre_parlamento', 'jurisdiccion', 'nombre_circunscripcion', | |
'tipo_circunscripcion', 'partido_politico', | |
'grupo_parlamentario', 'url', 'email'] | |
out.writerow(cabeceras) | |
for item in urls: | |
data = extraer_datos(item) | |
row = [data['id_parlamentario'], data['nombre_apellidos'], | |
data['nombre'], data['apellido_1'], data['apellido_2'], | |
data['fecha_inicio'], data['fecha_fin'], data['legislatura'], | |
data['nombre_parlamento'], data['jurisdiccion'], | |
data['nombre_circunscripcion'], data['tipo_circunscripcion'], | |
data['partido_politico'], data['grupo_parlamentario'], | |
data['url'], data['email']] | |
print row # Para debug, también útil para ver la marcha del script | |
out.writerow(row) | |
if __name__ == '__main__': | |
urls = get_urls_senadores(url) | |
crear_csv(urls, outfile) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey... lo estoy corriendo pero me da un error,.
You have new mail.
You have new mail.
cd '/Users/mpmetal/Downloads/sacardatos/' && '/usr/bin/pythonw' '/Users/mpmetal/Downloads/sacardatos/senado_novena.py' && echo Exit status: $? && exit 1
Imac-Mp:~ mpmetal$ cd '/Users/mpmetal/Downloads/sacardatos/' && '/usr/bin/pythonw' '/Users/mpmetal/Downloads/sacardatos/senado_novena.py' && echo Exit status: $? && exit 1
Traceback (most recent call last):
File "/Users/mpmetal/Downloads/sacardatos/senado_novena.py", line 27, in
from lxml.html import parse
ImportError: No module named lxml.html
Imac-Mp:sacardatos mpmetal$