Guía de análisis de HTML
Analiza los archivos HTML de VuSitu o HydroVu utilizando los grupos, las propiedades y otros atributos XML que se enumeran a continuación. Utiliza el analizador de ejemplo escrito en Python en la parte inferior de esta página como modelo para tu propia secuencia de comandos, o personaliza el código para que se ajuste a tus necesidades. También proporcionamos varios archivos HTML de VuSitu que puedes usar para realizar pruebas.
Grupos
LocationProperties
ReportProperties
InstrumentProperties
LogProperties
TestProperties
WellProperties
PumpProperties
TubingProperties
Propiedades de ubicación
Nombre
GUID
Latitud
Longitud
Propiedades del informe
Hora de inicio
Creado
Duración
Lecturas
Desplazamiento de tiempo
IPropiedades del instrumento
Modelo
Número de serie
Versión de firmware
Propiedades de registro
LogType
Nombre
GUID
FileNumber
LogWrapping
LogLinearProperties
Intervalo
LogLogarithmicProperties
Intervalo
LogLinearAverageProperties
Interval
AveragingInterval
SampleSize
LogStepProperties
Interval
Contar
Duración
LogEventProperties
SamplingInterval
DefaultInterval
HighThreshold
LowThreshold
ChangeThreshold
ChangeSinceLastLoggedThreshold
LowFlowTestProperties
TestType
StartTime
TimeOffset
ProjectName
OperatorName
FlowCellVolume
InitialDepthToWater
FinalDrawDown
TotalSystemVolume
TotalPumpedVolume
WellProperties
CasingType
Diámetro
Longitud
TotalDepth
DepthToScreen
ScreenLength
Propiedades de la bomba
Modelo FlowRate Volumen IntakeFromTopOfCasing FinalPumpingRate
TubingProperties
TubingType
Diámetro
Longitud
Atributos XML:
- isi-group:
Define el identificador que utilizarán los miembros de isi-group para agruparse lógicamente.
Example: isi-group="LocationProperties"
- isi-group-member:
Identifica el elemento como un miembro del grupo.
Ejemplo: isi-group-member="LocationProperties"
- isi-property:
Identifica el elemento como "property", en forma de <Key> <Value>
<tr isi-property="Name"><td>Name = My Location</td></tr>
- isi-label:
Identifica el elemento como una etiqueta localizada, para aislarlo del lado del valor
Ejemplo:<tr><td><span isi-label="">Name</span> = My Location</td></tr>
- isi-value:
Instruye al analizador que el elemento actual contiene un valor Ejemplo:
<tr><td>Name = <span isi-value="">My Location</span></td></tr>
- isi-text-node:
Enseña al analizador que el valor no existe como un atributo del elemento actual, ejemplo:
<tr><td isi-text-node="">Name = My Location</td></tr>
- isi-datetime:
Proporciona una cadena con formato de fecha y hora estándar ISO, ejemplo:
<tr><td isi-datetime="2017-10-08T13:05:30-06:00">Start Time = 10/08/2017 1:05 PM</td></tr>
- isi-timespan-milliseconds:
Proporciona una duración de milisegundos entero, ejemplo:
<tr><td isi-timespan-milliseconds="3600000">Duration = 01:00:00</td></tr>
- isi-enabled: Proporciona un valor booleano como una cadena. Ejemplo:
<tr><td isi-enabled="True">Log Wrapping Enabled = True</td></tr>
- isi-device-type: Proporciona un valor entero que representa el modelo del dispositivo (tipo de dispositivo de especificaciones del sistema), ejemplo:
<tr><td isi-device-type="7">Model = Aqua TROLL 600</td></tr>
- isi-log-type: Proporciona un valor entero que representa el tipo de registro.
- isi-data-column-header: Indica que el elemento actual es un encabezado de columna de datos, ejemplo:
<tr><td isi-data-column-header="">Temperature (F)</td></tr>
- isi-device-serial-number: Proporciona un número de serie del dispositivo. Ejemplo:
<tr><td isi-device-serial-number="1234">Temperature (F)</td></tr>
- isi-sensor-serial-number: Proporciona un número de serie del sensor, ejemplo:
<tr><td isi-sensor-serial-number="4567">Temperature (F)</td></tr>
- isi-device-sensor-type: Proporciona un tipo de sensor (tipo de sensor de especificaciones del sistema), ejemplo:
<tr><td isi-sensor-type="1">Temperature (F)</td></tr>
- isi-external-parameter: Indica que un sensor proviene de una fuente externa (que no forma parte del instrumento), ejemplo:
<tr><td isi-external-parameter="">Temperature (F)</td></tr>
- isi-parameter-type: Proporciona un tipo de parámetro de sensor (tipo de parámetro de especificación del sistema), ejemplo:
<tr><td isi-parameter-type="1">Temperature (F)</td></tr>
- isi-unit-type: Proporciona un tipo de unidad de sensor (tipo de unidad de especificación del sistema), ejemplo:
<tr><td isi-unit-type="2">Temperature (F)</td></tr>
- isi-data-table: Indica el inicio de una tabla de datos de series temporales. Ejemplo:
<tr isi-data-table=""><td>Temperature (F)</td></tr>
- isi-data-row: Indica una fila de datos de una tabla de datos de series temporales. Ejemplo:
<tr isi-data-row=""><td>98.6</td><td>32.0</td><td>100.0</td></tr>
- isi-timestamp: Proporciona una forma entera de tiempo de especificación del sistema (definición interna), ejemplo:
<tr isi-timestamp="238900"><td>07/16/1969 20:18:00</td><td>100.0</td></tr>
- isi-data-quality: Indica que los datos de una tabla de datos de series temporales tienen un valor de calidad no normal (especificación del sistema Tipo de calidad de datos), ejemplo:
<tr><td>98.6</td><td>32.0</td><td>100.0</td><td isi-data-quality="3">0</td></tr>
- isi-marked: Indica que se marcaron los datos de una tabla de datos de series temporales (toda la fila), ejemplo:
<tr isi-marked=""><td>98.6</td><td>32.0</td><td>100.0</td></tr>
- isi-log-note: Indica que el elemento actual es parte de una nota de registro, ejemplo:
<tr><td isi-log-note="">10/08/2012 15:30:00 Sensor Changed</td></tr>
- isi-log-note-type: Proporciona el tipo de nota de registro como un número entero (tipo de nota de registro de especificaciones del sistema), ejemplo:
<tr><td isi-log-note-type="12">10/08/2012 15:30:00 Sensor Changed</td></tr>
- isi-lowflow-sample: Indica que el elemento actual es parte de una muestra de flujo bajo. Ejemplo:
<tr><td isi-lowflow-sample=""><span isi-label="">Sample #931</span>: <span isi-value="">Pre test sample</span></td></tr>
- isi-lowflow-note:
<tr><td isi-lowflow-note=""><span>Weather Conditions</span>: <span>38.5 F, 78% humidity</span></td></tr>
Notas sobre el análisis del archivo
- Los datos a analizar comienzan en la etiqueta:
<table id="isi-report">
- Los datos están organizados por fila de tabla
<tr>
y luego<td>
elementos en esa fila: - NO analizar en función del atributo de clase. El atributo de clase solo se usa para formatear dentro de Excel y debe tratarse como opcional
- Análisis basado en los atributos XML enumerados anteriormente (por ejemplo: isi-group).
Ejemplo de analizador (Python 2x)
desde HTMLParser importar HTMLParser
# hacer una versión personalizada del analizador HTML con anulaciones para manejar los elementos de datos
clase MyHTMLParser(HTMLParser):
def FeedLine (auto, línea, reinicio):
si se reinicia:
self.startStack = [];
self.endStack = []
self.elements = []
self.feed(line)
def handle_starttag(self, tag, attrs):
self.startStack.append(tag)
self.elements.append({})
if len(attrs) > 0:
self.elements[-1]["attrs"] = attrs
def handle_endtag(self, tag):
self.endStack.append(tag)
def handle_data(self, data):
if data.strip() == "" or data.strip().rstrip() == "=":
volver
if len(self.elements) < 1:
volver
self.elements[-1]["data"] = data
# obtener el atributo del tipo provisto de una lista de atributos
def GetAttr(attrs, ofType):
for attr in attrs:
if attr[0] == ofType:
return attr
devuelve None
# determinar si la lista de atributos contiene el tipo proporcionado
def ContainsAttr(attrs, ofType):
devuelve GetAttr(attrs, ofType) no es None
# escanear a través de todos los elementos en una lista de elementos buscando el atributo del tipo provisto
def GetAttrFromElements(elements, ofType):
para elemento en elementos:
si 'attrs' no está en el elemento:
continúa
for attr in element['attrs']:
if attr[0] == ofType:
return attr
devuelve None
def GetClass(elements):
attr = GetAttrFromElements(elements, 'class')
Si attr es None:
devuelve None
más:
devuelve attr[1]
parser = MyHTMLParser()
# estructuras de datos para contener los datos del archivo
metadataGroups = {}
dataTables = []
# abrir el archivo de datos in-situ
fptr = open('YOUR FILENAME HERE', 'r')
# pasar del html de visualización a los datos que nos interesan
para línea en fptr:
parser.FeedLine(line, True)
if 'body' in parser.startStack:
break
# leer el archivo línea por línea para ahorrar memoria
resetLine = True
para línea en fptr:
parser.FeedLine(line, resetLine)
resetLine = True
# solo te interesan las filas de la tabla, así que si no es un tr, ve a la siguiente línea
if "tr" not in parser.startStack:
continúa
# asegúrate de que tengamos una fila completa de la tabla cargada, no solo una línea
if "tr" not in parser.endStack:
resetLine = False
continúa
# omitir líneas en blanco
si len(parser.elements) < 1 o 'attrs' no está en parser.elements[0]:
continúa
startIndex = parser.startStack.index('tr')
rootAttr = parser.elements[startIndex]['attrs']
para el elemento en parser.elements[startIndex:]:
# si el elemento no tiene atributos podemos ignorarlo
si 'attrs' no está en el elemento:
continúa
if ContainsAttr(element['attrs'], 'isi-group'):
attr = GetAttr(element['attrs'], 'isi-group')
metadataGroups[attr[1]] = {}
metadataGroups[attr[1]]["Name"] = attr[1]
elif ContainsAttr(element['attrs'], 'isi-group-member'):
attr = GetAttr(element['attrs'], 'isi-group-member')
metaData = parser.elements[1]['attrs']
groupName = GetAttr(metaData, 'isi-group-member')[1]
isiProperty = GetAttr(element['attrs'], 'isi-property')
Si isiProperty no es ninguna:
label = parser.elements[2]['data']
value = parser.elements[3]['data']
metadataGroups[groupName][isiProperty[1]] = {'Label': label, 'Value': value}
logNotes = GetAttr(element['attrs'], 'isi-log-note')
if logNotes is not None:
if "Notes" not in parser.elements[1]['attrs']:
metadataGroups[groupName]["Notes"] = []
for attr in parser.elements[1]['attrs']:
metadataGroups[groupName]["Notes"].append({attr[0]:attr[1]})
elif ContainsAttr(element['attrs'], 'isi-data-table'):
dataTables.append({'Headers': [], 'Values': []})
elif ContainsAttr(element['attrs'], 'isi-data-column-header'):
hold = {'Name': element['data']}
para attr en el elemento:
hold[attr[0]] = attr[1]
dataTables[-1]['Headers'].append(hold)
elif ContainsAttr(element['attrs'], 'isi-data-row'):
hold = []
# todos los elementos en esta fila son datos, así que procésalos todos y luego rompe
para el elemento en parser.elements:
si 'attrs' en el elemento y ContainsAttr(element['attrs'], 'isi-data-row'): # no hay datos en la configuración de la fila
continúa
elif 'datos' en el elemento:
hold.append(element['data'])
más:
hold.append(' ')
dataTables[-1]['Values'].append(hold)
# imprimir los metadatos del archivo.
para clave en metadataGroups.iterkeys():
imprimir (clave)
imprimir ("\t", metadataGroups[key])
imprimir ("\n")
# imprimiendo los datos
para tabla en dataTables:
# impresión de fila de encabezado para todos los datos - NOTA: hay metadatos como el tipo de sensor que no se imprimen aquí
para el encabezado en table['Headers']:
imprimir (header['Name'] + "\t",)
imprimir ("")
# imprimiendo la fila de datos - mismo orden que los encabezados para que puedas asociarlos correctamente
para la fila en table['Values']:
para dato en fila:
imprimir ("|" + datum + "|",)
imprimir ("")
Ejemplo de analizador (Python 3x)
desde html.parser importar HTMLParser
# hacer una versión personalizada del analizador HTML con anulaciones para manejar los elementos de datos
clase MyHTMLParser(HTMLParser):
def FeedLine (auto, línea, reinicio):
si se reinicia:
self.startStack = []
self.endStack = []
self.elements = []
self.feed(line)
def handle_starttag(self, tag, attrs):
self.startStack.append(tag)
self.elements.append({})
if len(attrs) > 0:
self.elements[-1]["attrs"] = attrs
def handle_endtag(self, tag):
self.endStack.append(tag)
def handle_data(self, data):
if data.strip() == "" or data.strip().rstrip() == "=":
volver
if len(self.elements) < 1:
volver
self.elements[-1]["data"] = data
# obtener el atributo del tipo provisto de una lista de atributos
def GetAttr(attrs, ofType):
for attr in attrs:
if attr[0] == ofType:
return attr
devuelve None
# determinar si la lista de atributos contiene el tipo proporcionado
def ContainsAttr(attrs, ofType):
devuelve GetAttr(attrs, ofType) no es None
# escanear a través de todos los elementos en una lista de elementos buscando el atributo del tipo provisto
def GetAttrFromElements(elements, ofType):
para elemento en elementos:
si 'attrs' no está en el elemento:
continúa
for attr in element['attrs']:
if attr[0] == ofType:
return attr
devuelve None
def GetClass(elements):
attr = GetAttrFromElements(elements, 'class')
Si attr es None:
devuelve None
más:
devuelve attr[1]
parser = MyHTMLParser()
# estructuras de datos para contener los datos del archivo
metadataGroups = {}
dataTables = []
# abrir el archivo de datos in-situ
fptr = open('YOUR FILENAME HERE', 'r')
# pasar del html de visualización a los datos que nos interesan
para línea en fptr:
parser.FeedLine(line, True)
if 'body' in parser.startStack:
break
# leer el archivo línea por línea para ahorrar memoria
resetLine = True
para línea en fptr:
parser.FeedLine(line, resetLine)
resetLine = True
# solo te interesan las filas de la tabla, así que si no es un tr, ve a la siguiente línea
if "tr" not in parser.startStack:
continúa
# asegúrate de que tengamos una fila completa de la tabla cargada, no solo una línea
if "tr" not in parser.endStack:
resetLine = False
continúa
# omitir líneas en blanco
si len(parser.elements) < 1 o 'attrs' no está en parser.elements[0]:
continúa
startIndex = parser.startStack.index('tr')
rootAttr = parser.elements[startIndex]['attrs']
para el elemento en parser.elements[startIndex:]:
# si el elemento no tiene atributos podemos ignorarlo
si 'attrs' no está en el elemento:
continúa
if ContainsAttr(element['attrs'], 'isi-group'):
attr = GetAttr(element['attrs'], 'isi-group')
metadataGroups[attr[1]] = {}
metadataGroups[attr[1]]["Name"] = attr[1]
elif ContainsAttr(element['attrs'], 'isi-group-member'):
attr = GetAttr(element['attrs'], 'isi-group-member')
metaData = parser.elements[1]['attrs']
groupName = GetAttr(metaData, 'isi-group-member')[1]
isiProperty = GetAttr(element['attrs'], 'isi-property')
Si isiProperty no es ninguna:
label = parser.elements[2]['data']
value = parser.elements[3]['data']
metadataGroups[groupName][isiProperty[1]] = {'Label': label, 'Value': value}
logNotes = GetAttr(element['attrs'], 'isi-log-note')
if logNotes is not None:
if "Notes" not in parser.elements[1]['attrs']:
metadataGroups[groupName]["Notes"] = []
for attr in parser.elements[1]['attrs']:
metadataGroups[groupName]["Notes"].append({attr[0]:attr[1]})
elif ContainsAttr(element['attrs'], 'isi-data-table'):
dataTables.append({'Headers': [], 'Values': []})
elif ContainsAttr(element['attrs'], 'isi-data-column-header'):
hold = {'Name': element['data']}
para attr en el elemento:
hold[attr[0]] = attr[1]
dataTables[-1]['Headers'].append(hold)
elif ContainsAttr(element['attrs'], 'isi-data-row'):
hold = []
# todos los elementos en esta fila son datos, así que procésalos todos y luego rompe
para el elemento en parser.elements:
si 'attrs' en el elemento y ContainsAttr(element['attrs'], 'isi-data-row'): # no hay datos en la configuración de la fila
continúa
elif 'datos' en el elemento:
hold.append(element['data'])
más:
hold.append(' ')
dataTables[-1]['Values'].append(hold)
# imprimir los metadatos del archivo.
para clave en metadataGroups.keys():
imprimir (clave)
imprimir ("\t", metadataGroups[key])
imprimir ("\n")
# imprimiendo los datos
para tabla en dataTables:
# impresión de fila de encabezado para todos los datos - NOTA: hay metadatos como el tipo de sensor que no se imprimen aquí
para el encabezado en table['Headers']:
imprimir (header['Name'] + "\t",)
imprimir ("")
# imprimiendo la fila de datos - mismo orden que los encabezados para que puedas asociarlos correctamente
para la fila en table['Values']:
para dato en fila:
imprimir ("|" + datum + "|",)
imprimir ("")