簡體   English   中英

如何使用python(bs4)閱讀特定的html行

[英]How to read specific html lines with python (bs4)

首先,我是python和beautifulsoup的新手。

我無權訪問html代碼中鏈接的css,js文件。 我也不能修改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)為單位,有些不是壓力(bar),因此我還需要獲得bar的最小值或最大值。 我該怎么做呢?
而且我還想找出哪個值恰好超過了最小值或最大值,並包括其名稱和度數或bar(名稱在列表var_name中找到,但是索引不一樣,因為列表行/數據中的某些數據得到了還試圖切掉document.write();僅使用.text.strip()來獲得實際的名字是行不通的,但是需要過濾,因為否則我無法將字符串轉換為浮點數。
例如,如果我們說“ Aussentemperatur”(html代碼行158)是200.0,而不是1.4,則輸出到csv文件中的期望輸出將是:
奧森溫度,200,°C
如果有更多的值超過,則保持輸出。
由於我不知道鹽水熱泵的行為,因此在構建html頁面時,我希望它寫一些字符串。 在這種情況下,我還想輸出給定的字符串:
奧氏體溫度,未知弦,°C

編輯:我將代碼編輯為當前狀態並添加了新段落

您可以基於是否是°Cbar條目的正確格式條目來決定要包括的行。 可以使用正則表達式從腳本文本中提取傳感器類型。

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

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])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM