screen scraping - spider - ¿Cómo puedo raspar una tabla HTML a CSV?
web scraper python 3 (11)
Aún más fácil (porque se lo guarda para la próxima vez) ...
En Excel
Datos / Importar datos externos / Nueva consulta web
lo llevará a un aviso de url. Ingrese su url y delimitará las tablas disponibles en la página para importar. Voila.
El problema
Utilizo una herramienta en el trabajo que me permite hacer consultas y recuperar tablas HTML de información. No tengo ningún tipo de acceso de fondo a la misma.
Mucha de esta información sería mucho más útil si pudiera ponerla en una hoja de cálculo para ordenar, promediar, etc. ¿Cómo puedo raspar la pantalla de estos datos en un archivo CSV?
Mi primera idea
Como conozco jQuery, pensé que podría usarlo para quitar el formato de la tabla en pantalla, insertar comas y saltos de línea, y simplemente copiar todo el desorden en el bloc de notas y guardarlo como un CSV. Alguna mejor idea?
La solución
Sí, amigos, realmente fue tan fácil como copiar y pegar. No me siento tonto
Específicamente, cuando pegué en la hoja de cálculo, tuve que seleccionar "Pegar especial" y elegir el formato "texto". De lo contrario, intentó pegar todo en una sola celda, incluso si resalté toda la hoja de cálculo.
¿Has intentado abrirlo con Excel? Si guarda una hoja de cálculo en excel como html, verá el formato que usa Excel. Desde una aplicación web que escribí escupí este formato html para que el usuario pueda exportar a Excel.
Rápido y sucio:
Copie fuera del navegador en Excel, guárdelo como CSV.
Mejor solución (para uso a largo plazo):
Escribe un poco de código en el idioma que elijas, que extraerá el contenido html y eliminará los bits que quieras. Probablemente puedas incluir todas las operaciones de datos (clasificación, promediado, etc.) además de la recuperación de datos. De esta forma, solo tiene que ejecutar su código y obtener el informe real que desea.
Todo depende de la frecuencia con la que realizarás esta tarea en particular.
Si está explorando la pantalla y la tabla que está tratando de convertir tiene una ID determinada, siempre puede hacer un análisis regex del html junto con algunos scripts para generar un CSV.
- Seleccione la tabla HTML en la interfaz de usuario de sus herramientas y cópiela en el portapapeles (si eso es posible)
- Pégalo en Excel.
- Guardar como archivo CSV
Sin embargo, esta es una solución manual no automatizada.
usando python:
por ejemplo, imagine que desea raspar las cotizaciones de divisas en formato csv de algún sitio como: fxquotes
entonces...
from BeautifulSoup import BeautifulSoup
import urllib,string,csv,sys,os
from string import replace
date_s = ''&date1=01/01/08''
date_f = ''&date=11/10/08''
fx_url = ''http://www.oanda.com/convert/fxhistory?date_fmt=us''
fx_url_end = ''&lang=en&margin_fixed=0&format=CSV&redirected=1''
cur1,cur2 = ''USD'',''AUD''
fx_url = fx_url + date_f + date_s + ''&exch='' + cur1 +''&exch2='' + cur1
fx_url = fx_url +''&expr='' + cur2 + ''&expr2='' + cur2 + fx_url_end
data = urllib.urlopen(fx_url).read()
soup = BeautifulSoup(data)
data = str(soup.findAll(''pre'', limit=1))
data = replace(data,''[<pre>'','''')
data = replace(data,''</pre>]'','''')
file_location = ''/Users/location_edit_this''
file_name = file_location + ''usd_aus.csv''
file = open(file_name,"w")
file.write(data)
file.close()
editar: para obtener valores de una tabla: ejemplo de: palewire
from mechanize import Browser
from BeautifulSoup import BeautifulSoup
mech = Browser()
url = "http://www.palewire.com/scrape/albums/2007.html"
page = mech.open(url)
html = page.read()
soup = BeautifulSoup(html)
table = soup.find("table", border=1)
for row in table.findAll(''tr'')[1:]:
col = row.findAll(''td'')
rank = col[0].string
artist = col[1].string
album = col[2].string
cover_link = col[3].img[''src'']
record = (rank, artist, album, cover_link)
print "|".join(record)
Esta es mi versión de Python usando la última versión (actual) de BeautifulSoup que se puede obtener usando, por ejemplo,
$ sudo easy_install beautifulsoup4
La secuencia de comandos lee HTML de la entrada estándar y emite el texto que se encuentra en todas las tablas en el formato CSV adecuado.
#!/usr/bin/python
from bs4 import BeautifulSoup
import sys
import re
import csv
def cell_text(cell):
return " ".join(cell.stripped_strings)
soup = BeautifulSoup(sys.stdin.read())
output = csv.writer(sys.stdout)
for table in soup.find_all(''table''):
for row in table.find_all(''tr''):
col = map(cell_text, row.find_all(re.compile(''t[dh]'')))
output.writerow(col)
output.writerow([])
Dos maneras vienen a la mente (especialmente para aquellos de nosotros que no tienen Excel):
- Google Spreadsheets tiene una excelente función de
importHTML
:-
=importHTML("http://example.com/page/with/table", "table", index
- El índice comienza en 1
- Recomiendo
copy
ypaste values
poco después de la importación - Archivo -> Descargar como -> CSV
-
- La magnífica biblioteca Pandas de Python tiene prácticas funciones
read_html
yto_csv
- Aquí hay un script básico de Python3 que solicita la URL, qué tabla en esa URL y un nombre de archivo para el CSV.
Implementación básica de Python usando BeautifulSoup, también considerando tanto rowspan como colspan:
from BeautifulSoup import BeautifulSoup
def table2csv(html_txt):
csvs = []
soup = BeautifulSoup(html_txt)
tables = soup.findAll(''table'')
for table in tables:
csv = ''''
rows = table.findAll(''tr'')
row_spans = []
do_ident = False
for tr in rows:
cols = tr.findAll([''th'',''td''])
for cell in cols:
colspan = int(cell.get(''colspan'',1))
rowspan = int(cell.get(''rowspan'',1))
if do_ident:
do_ident = False
csv += '',''*(len(row_spans))
if rowspan > 1: row_spans.append(rowspan)
csv += ''"{text}"''.format(text=cell.text) + '',''*(colspan)
if row_spans:
for i in xrange(len(row_spans)-1,-1,-1):
row_spans[i] -= 1
if row_spans[i] < 1: row_spans.pop()
do_ident = True if row_spans else False
csv += ''/n''
csvs.append(csv)
#print csv
return ''/n/n''.join(csvs)
Aquí hay un ejemplo probado que combina grequest y sopa para descargar grandes cantidades de páginas de un sitio web estructurado:
#!/usr/bin/python
from bs4 import BeautifulSoup
import sys
import re
import csv
import grequests
import time
def cell_text(cell):
return " ".join(cell.stripped_strings)
def parse_table(body_html):
soup = BeautifulSoup(body_html)
for table in soup.find_all(''table''):
for row in table.find_all(''tr''):
col = map(cell_text, row.find_all(re.compile(''t[dh]'')))
print(col)
def process_a_page(response, *args, **kwargs):
parse_table(response.content)
def download_a_chunk(k):
chunk_size = 10 #number of html pages
x = "http://www.blahblah....com/inclusiones.php?p="
x2 = "&name=..."
URLS = [x+str(i)+x2 for i in range(k*chunk_size, k*(chunk_size+1)) ]
reqs = [grequests.get(url, hooks={''response'': process_a_page}) for url in URLS]
resp = grequests.map(reqs, size=10)
# download slowly so the server does not block you
for k in range(0,500):
print("downloading chunk ",str(k))
download_a_chunk(k)
time.sleep(11)
Excel puede abrir una página http.
P.ej:
Haga clic en Archivo, Abrir
Debajo de nombre de archivo, pegue la URL, es decir: ¿Cómo puedo raspar una tabla HTML a CSV?
Haga clic en Aceptar
Excel hace todo lo posible para convertir el html en una tabla.
No es la solución más elegante, ¡pero funciona!