Este programa extrae todas las tabulaciones tradicionales en en un archivo HTML local y las guarda en un archivo de Excel, donde cada tabla tendrá su hoja. En este ejemplo se extrae el texto o los links de las imagenes dependiendo de lo que contenga la tabla..
Para correr este programa se requiere Python 3 y las librerías conocidas como wxpython, Beautifulsoup y oprnpyxl. Se instalan fácilmente usando pip.
El código fuente esta comentado para que sepas lo que sucede.
import wx
import wx.lib.agw.hyperlink as hl
from os import getcwd
from openpyxl import Workbook
from openpyxl.styles import Border,Side, Alignment, Font, Color, PatternFill
from bs4 import BeautifulSoup
class MyFrame(wx.Frame):
def __init__(self, parent, title ="Extractor de Tablas HTML"):
super().__init__(parent, title = title , size = (600,240))
self.SetMinSize(size = (600,240)) #Set minimum size to current
self.locale = wx.Locale(wx.LANGUAGE_ENGLISH) # Fix locale unknown error
self.Dir = "" #directorio por defecto
self.DirSve = getcwd()+"\DefaultName.xlsx" #directorio por defecto guardar
self.wb = Workbook()
#--------------------------------------------------
# Widgets
#---------------------------------------------------
self.CreateStatusBar()
self.SetStatusText("")
panel = wx.Panel(self, wx.ID_ANY)
BtnDirSrch = wx.Button(panel, label="HTML")
self.TxtDirSrch = wx.TextCtrl( panel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
self.TxtDirSrch.SetEditable(False)
self.TxtDirSrch.SetValue("")
BtnDirRes = wx.Button(panel, label="Dir. Guardar")
self.TxtDirRes = wx.TextCtrl( panel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
self.TxtDirRes.SetEditable(False)
self.TxtDirRes.SetValue(self.DirSve)
BtnProcesar = wx.Button(panel, label="Crear Tabla de Excel")
LblDeveloper = wx.StaticText(panel,-1, style = wx.ALIGN_CENTER | wx.ST_ELLIPSIZE_MIDDLE)
LblDeveloper.SetLabel("http://mecatroncharly.blogspot.com")
LblDeveloper.SetForegroundColour((255,255,255))
LblDeveloper.SetBackgroundColour((0,0,0))
hyper1 = hl.HyperLinkCtrl(panel, -1, "http://mecatroncharly.blogspot.com",
URL="http://mecatroncharly.blogspot.com")
hyper1.SetColours("BLUE", "BLUE", "BLUE")
#--------------------------------------------------
# BINDS
#--------------------------------------------------
BtnProcesar.Bind(wx.EVT_BUTTON, self.onProcesar )
BtnDirSrch .Bind(wx.EVT_BUTTON, self.onSetDirHtml)
BtnDirRes .Bind(wx.EVT_BUTTON, self.onSetDirSve )
#--------------------------------------------------
# LAYOUT
#--------------------------------------------------
MainSizer = wx.BoxSizer(wx.VERTICAL)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizerBtns = wx.BoxSizer(wx.VERTICAL)
sizerDir = wx.BoxSizer(wx.VERTICAL)
sizerBtns.Add(BtnDirSrch, 0, wx.ALL|wx.CENTER, 5)
sizerBtns.Add(BtnDirRes, 0, wx.ALL|wx.CENTER, 5)
sizerDir.Add(self.TxtDirSrch, 1, wx.ALL|wx.CENTER|wx.EXPAND, 5)
sizerDir.Add(self.TxtDirRes, 1, wx.ALL|wx.CENTER|wx.EXPAND, 5)
sizer.Add(sizerBtns, 0,wx.EXPAND)
sizer.Add(sizerDir, 1,wx.EXPAND)
MainSizer.Add(sizer, 0,wx.EXPAND)
MainSizer.Add(BtnProcesar,1,wx.EXPAND,5)
MainSizer.Add(hyper1,0,wx.EXPAND,5)
panel.SetSizer(MainSizer)
def onProcesar (self, event):
if self.Dir == '': #prevenir errores causados por descuido del usiario.
wx.MessageBox('No has elegido el archivo HTML', 'Info', wx.OK | wx.ICON_INFORMATION)
return
GetBusy = wx.BusyInfo("Procesandio, por favor espere", self) #Mostrar Leyenda (ocupado)
#-----------------------------------------------------------------------------------------
file = open(self.Dir, 'r') # abrir archivo
theString = file.read() # Obtener texto
soup = BeautifulSoup(theString, 'lxml') # frasear el archivo HTML
tables = soup.find_all('table') # Encontrar tablas HTML
#-----------------------------------------------------
# Estilos a usar en la hoja de Excel
#-----------------------------------------------------
Borders = Border(left = Side(style='thin'),
right = Side(style='thin'),
top = Side(style='thin'),
bottom = Side(style='thin'))
ALCentered = Alignment(horizontal = 'center',vertical = 'center')
FuenteHdr = Font(bold = True)
#-----------------------------------------------------
# Iterar sobre las tablas que fueron encontradas
#-----------------------------------------------------
for x in range(len(tables)): #iterar sobre las tablas
ws = self.wb.create_sheet('Tabla '+str(x+1))
self.wb.active = x
HdrCols = 1
#-----------------------------------------------------
# Encontrar encabezados y ponerlos en el documento
#-----------------------------------------------------
for Hdr in tables[x].find_all('th'): #iterar sobre encabezados de esta tabla
ws.cell(row = 1,
column = HdrCols,
value = Hdr.get_text()).border = Borders
ws.cell(row = 1, column = HdrCols).alignment = ALCentered
ws.cell(row = 1, column = HdrCols).font = FuenteHdr
HdrCols += 1
#-----------------------------------------------------
# Encontrar Datos de la tabla
#-----------------------------------------------------
row_marker = 0
for row in tables[x].find_all('tr'):
columns = row.find_all('td')
column_marker = 1
row_marker += 1
for column in columns:
img = column.find('img') #encontrar si tiene una imagen
if img: #Si tiene una imagen, extraer el link
txtImg = img.get('src')
ws.cell(row = row_marker,
column = column_marker,
value = txtImg).border = Borders
else: #Si no tiene una imagen, extraer el texto
ws.cell(row = row_marker,
column = column_marker,
value = column.get_text()).border = Borders
ws.cell(row = row_marker, column = column_marker).alignment = ALCentered
column_marker += 1
del self.wb["Sheet"] # hoja se crea por defecto,la borramos porque no la queremos
self.wb.save(self.DirSve) # Guardar
#------------------------------------------------------------------------------------
del GetBusy # quitar leyenda (ocupado)
wx.MessageBox('Se ha creado la tabla de Excel', 'Info', wx.OK | wx.ICON_INFORMATION)
def onSetDirHtml(self, event):
wildcard = "HTML (*.html)|*.html"
dlg = wx.FileDialog(self,
message = "Choose a file",
defaultDir = self.Dir,
defaultFile = "",
wildcard = wildcard,
style = wx.FD_OPEN)
if dlg.ShowModal() == wx.ID_OK:
self.Dir = dlg.GetPath()
self.TxtDirSrch.SetValue(self.Dir)
dlg.Destroy()
print(self.Dir)
def onSetDirSve(self, event):
wildcard = "Archivos de Excel(*.xlsx)|*.xlsx"
dlg = wx.FileDialog(
self, message="Elegir dereccion y numbre",
defaultDir=self.DirSve,
defaultFile="", wildcard=wildcard, style=wx.FD_SAVE
)
if dlg.ShowModal() == wx.ID_OK:
self.DirSve = dlg.GetPath()
self.TxtDirRes.SetValue(self.DirSve)
dlg.Destroy()
print(self.DirSve)
app = wx.App(0)
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()
puedes usar este ejemplo de una tabla HTML:
<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
text-align: left;
}
</style>
</head>
<body>
<h2>Table Caption</h2>
<p>To add a caption to a table, use the caption tag.</p>
<table style="width:100%">
<caption>Monthly savings</caption>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>February</td>
<td>$50</td>
</tr>
</table>
</body>
</html>
No hay comentarios.:
Publicar un comentario