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:
 Indica que el elemento actual contiene una nota Low-Flow, ejemplo:

<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 ("")

Archivos HTML de VuSitu de muestra

Registro de muestra 1

Registro de muestra 2

Registro de muestra 3

Registro de muestra 4

Registro de muestra 5

Headquarters: 221 E. Lincoln Ave, Fort Collins, CO, 80524, USA