Как читать определенные строки HTML с Python (BS4) - PullRequest
0 голосов
/ 06 февраля 2019

сначала я новичок в python и Beautifulsoup.

У меня нет доступа к файлам css, js, которые связаны в HTML-код.Также я не могу изменить html-страницу.
Я нахожусь на Linux и использую python3, если это имеет значение.

У меня есть следующая страница: https://pastebin.com/VqRRe02P
Фактический HTML-код, которыйХостинг не отформатирован, я запустил код через онлайн-форматировщик HTML-кода.Поэтому строки, которые я изложу ниже, не будут на 100% правильными.

Это код, который я сейчас использую (не все реализованные функции):

import requests
import csv
from bs4 import BeautifulSoup, element
from operator import itemgetter

# ermöglicht schnelles Wechseln des Hosts (IP über die, das Interface lokal erreichbar ist)
a = 'http://192.168.68.128' # IP der Wärmepumpe
b = 'http://localhost' # für Entwicklungszwecke

# beziehe Daten vom Host
data = requests.get(b)

# lade Daten in BeautifulSoup
soup = BeautifulSoup(data.text, 'html.parser')

# Liste 'data' wird erstellt
data = []
var_name = []

# Alle Tabellen werden gesucht und in die Variable 'row' gespeichert
    for tr in soup.table.find_all('tr'):
        row = [td.text for td in tr.find_all('td')]
        var_name.append(row[0])
        if not row[1].startswith('\n') and row[2] in ['°C', 'bar']: # hier werden Filter angewendet, um nur relevante Daten zu speichern
        data.append(itemgetter(1)(row)) # die gefilterten Daten werden in die Liste 'data' gespeichert

print(var_name[2])


# die Strings von 'data' werden in den Datentyp float umgewandelt
data = list(map(float, data))

# hier werden die Unter- und Obergrenze festgelegt
 min_value = 0
max_value = 100

# Funktion überprüft, ob ein Wert die Untergrenze überschreitet
def check1():
    if data[1] < min_value:
        return(1)
    else:
        return(0)

    # Funktion überprüft, ob ein Wert die Obergrenze überschreitet
    def check2():
    if data[1] > max_value:
        return(1)
    else:
        return(0)

# Funktion überprüft, ob ein Fehler vorliegt
def check():
    if check1() + check2() is 2:
        return('Fehlercode: 2')
    if check1() + check2() is 1:
        return('Fehlercode: 1')
    else:
        return('OK')

if check() in 'Fehlercode: 2':
print('Email mit Fehlercode 2 senden')  # Platzhalter für Email Skript ausführen
if check() in 'Fehlercode: 1':
    print('Email mit Fehlercode 1 senden') # Platzhalter für Email Skript ausführen

 # Daten werden in eine CSV Datei namens 'auslesen.csv' gespeichert
with open('auslesen.csv', 'w') as auslesen:
    writer = csv.writer(auslesen)
    writer.writerow(data)
    auslesen.close()

/ *Мне нужно прочитать данные из элементов td в следующих строках, сохранить их в переменные и вывести их в текстовый файл, такой как «var1, var2, var3, ..».Строки: 158, 204, 264, 339, 557, 579, 920, 937, 954, 1023, 1042, 1114, 1168. * /

Теперь я могу проверить, является ли элемент данных спискаПревышение минимального или максимального значения.
Проблема не в том, что все значения приведены в градусах (° C), некоторые - в давлении (бар), поэтому мне также необходимо получить минимальное или максимальное значение для бара.Как мне это сделать?
И я также хочу выяснить, какое значение точно превысило минимальное или максимальное значение, и включить его имя и степень или полосу (имя найдено в списке var_name, но индекс не совпадает снекоторые данные из строки / данных списка фильтруются. Также попытка обрезки document.write (); получение только фактического имени с помощью .text.strip () не сработало. Однако фильтрация необходима, потому что в противном случае я не могуt преобразовать строки в числа с плавающей точкой.
Например, если мы скажем «Aussentemperatur» (строка кода html 158) вместо 200, то значение 1.4, желаемый вывод в файл csv будет:
Aussentemperatur, 200, ° C
и продолжайте вывод, если значения превышают другие.
Поскольку я не знаю, как ведет себя тепловой насос с рассолом, при создании html-страницы я ожидаю, что он напишет некоторую строку. В этом случае ятакже хочу вывести строку:
Aussentemperatur, unknownstring, ° C

Редактировать: я отредактировал код до текущего состояния и добавил новый абзац

1 Ответ

0 голосов
/ 07 февраля 2019

Вы можете решить, какие из ваших строк включить, основываясь на том, правильно ли это отформатированная запись, содержащая запись либо °C, либо bar.Тип датчика можно извлечь из текста сценария с помощью регулярного выражения.

from collections import defaultdict
from bs4 import BeautifulSoup
import csv
import re

with open('index.html') as f_html:
    html = f_html.read()

soup = BeautifulSoup(html, "html.parser")
readings = defaultdict(list)    # Hold per sensor readings in a dictionary

with open('output.csv', 'w', newline='') as f_output:
    csv_output = csv.writer(f_output)
    csv_output.writerow(['Sensor', 'Value', 'Unit'])

    for tr in soup.table.find_all('tr'):
        row = [td.text for td in tr.find_all('td')]

        if not row[1].startswith('\n') and row[2] in ['°C', 'bar']:
            sensor = re.search(r'\((.*?)\)', row[0]).group(1)   # Extract sensor name from script text
            value = float(row[1])
            unit = row[2]

            readings[sensor].append(value)
            csv_output.writerow([sensor, value, unit])

for sensor in sorted(readings):
    data = readings[sensor]
    print(f'{sensor}:\n  Min {min(data)}, Max {max(data)}, {data}')

Библиотека Python CSV может использоваться для простой записи строк данных, правильно отформатированных в файл.

Это даст вам CSV-файл, обобщенный следующим образом:

Sensor,Value,Unit
Aussentemperatur,1.4,°C
Vorlauftemperatur,28.0,°C
Vorlauftemperatur,28.0,°C
Vorlauftemperatur,27.1,°C
Vorlauftemperatur,28.0,°C
Vorlauftemperatur,0.0,°C
Ruecklauftemperatur,27.1,°C
Ruecklauftemperatur,27.1,°C
Ruecklauftemperatur,28.0,°C
Ruecklauftemperatur,27.1,°C
Ruecklaufsolltemperatur,18.0,°C
Temperatur,0.0,°C
Kollektortemperatur,28.3,°C
MiniTempGKZwei,0.0,°C
Temperatur,16.3,°C
Temperatur,-999.9,°C
Solltemperatur,25.8,°C
MiniTempGKDrei,0.0,°C
Temperatur,35.1,°C
Temperatur,28.3,°C
Temperatur,0.0,°C
Solltemperatur,25.8,°C
Abtauendefuehler,17.6,°C
TempSpeicherReg,35.1,°C
TempSpeicherReg,28.3,°C
TempSpeicherReg,0.0,°C
RLTempKp,0.0,°C
VlTempKp,0.0,°C
Heissgastemperatur,0.0,°C
Raumtemperatur,35.1,°C
Raumtemperatur,28.3,°C
Raumtemperatur,0.0,°C
Raumtemperatur,0.0,°C
Raumtemperatur,0.0,°C
Temperatur,41.6,°C
Warmwasser,45.0,°C
Temperatur,0.0,°C
Wuelleneintritt,16.3,°C
Wuellenaustritt,17.6,°C
Niederdrucksensor,9.6,bar
Vorlauftemperatur,0.0,°C

A defaultdict(list) можно использовать для создания списков всех показаний датчиков для каждого датчика.Затем его можно использовать для отображения всех значений впоследствии, а также для отображения минимального и максимального значения, найденного для каждого датчика.Например, выходные данные будут такими:

Abtauendefuehler:
  Min 17.6, Max 17.6, [17.6]
Aussentemperatur:
  Min 1.4, Max 1.4, [1.4]
Heissgastemperatur:
  Min 0.0, Max 0.0, [0.0]
Kollektortemperatur:
  Min 28.3, Max 28.3, [28.3]
MiniTempGKDrei:
  Min 0.0, Max 0.0, [0.0]
MiniTempGKZwei:
  Min 0.0, Max 0.0, [0.0]
Niederdrucksensor:
  Min 9.6, Max 9.6, [9.6]
RLTempKp:
  Min 0.0, Max 0.0, [0.0]
Raumtemperatur:
  Min 0.0, Max 35.1, [35.1, 28.3, 0.0, 0.0, 0.0]
Ruecklaufsolltemperatur:
  Min 18.0, Max 18.0, [18.0]
Ruecklauftemperatur:
  Min 27.1, Max 28.0, [27.1, 27.1, 28.0, 27.1]
Solltemperatur:
  Min 25.8, Max 25.8, [25.8, 25.8]
TempSpeicherReg:
  Min 0.0, Max 35.1, [35.1, 28.3, 0.0]
Temperatur:
  Min -999.9, Max 41.6, [0.0, 16.3, -999.9, 35.1, 28.3, 0.0, 41.6, 0.0]
VlTempKp:
  Min 0.0, Max 0.0, [0.0]
Vorlauftemperatur:
  Min 0.0, Max 28.0, [28.0, 28.0, 27.1, 28.0, 0.0, 0.0]
Warmwasser:
  Min 45.0, Max 45.0, [45.0]
Wuellenaustritt:
  Min 17.6, Max 17.6, [17.6]
Wuelleneintritt:
  Min 16.3, Max 16.3, [16.3]

Если посмотреть на этот вывод, это может означать, что вам может потребоваться отфильтровать минимальное и максимальное значения на основе значений для каждого датчика.

Если вы нене хотите обрабатывать значения вне диапазона 0-100 и затем использовать следующие строки:

        if 0 <= value <= 100:
            readings[sensor].append(value)
            csv_output.writerow([sensor, value, unit])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...