【问题标题】:Python Conditionally Add Class to <td> Tags in HTML TablePython有条件地将类添加到HTML表中的<td>标签
【发布时间】:2016-09-21 01:51:50
【问题描述】:

我有一些 csv 文件形式的数据,我正在将其读入 Python 并使用 Pandas 转换为 HTML 表格。

这里有一些示例数据:

name  threshold  col1 col2 col3
A     10         12   9    13
B     15         18   17   23
C     20         19   22   25

还有一些代码:

import pandas as pd
df = pd.read_csv("data.csv")
table = df.to_html(index=False)

这将创建以下 HTML:

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th>name</th>
      <th>threshold</th>
      <th>col1</th>
      <th>col2</th>
      <th>col3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A</td>
      <td>10</td>
      <td>12</td>
      <td>9</td>
      <td>13</td>
    </tr>
    <tr>
      <td>B</td>
      <td>15</td>
      <td>18</td>
      <td>17</td>
      <td>23</td>
    </tr>
    <tr>
      <td>C</td>
      <td>20</td>
      <td>19</td>
      <td>22</td>
      <td>25</td>
    </tr>
  </tbody>
</table>

不,如果值小于某个阈值,我想有条件地向 html 表中的每个单元格添加一个类。表中每一行的阈值都不同。

因此,鉴于上面的示例数据,我想将一个类 class="custom" 添加到名称为 A 的单元格 col2 和名称为 C 的单元格 col1 中。在 CSS 中,我会将单元格颜色填充为红色有“自定义”类。

结果会是这样的:

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th>name</th>
      <th>threshold</th>
      <th>col1</th>
      <th>col2</th>
      <th>col3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A</td>
      <td>10</td>
      <td>12</td>
      <td class="custom">9</td>
      <td>13</td>
    </tr>
    <tr>
      <td>B</td>
      <td>15</td>
      <td>18</td>
      <td>17</td>
      <td>23</td>
    </tr>
    <tr>
      <td>C</td>
      <td>20</td>
      <td class="custom">19</td>
      <td>22</td>
      <td>25</td>
    </tr>
  </tbody>
</table>

如何使用 Beautiful Soup 实现这一目标?

【问题讨论】:

    标签: python html pandas beautifulsoup


    【解决方案1】:

    使用 BeautifulSoup,您可以像在字典中设置键/值一样将类添加到标签 attrs:

    soup = BeautifulSoup(html,"html.parser")
    
    for row in soup.select("tbody tr"):
        tds = row.find_all("td")     
        if int(tds[3].text) < int(tds[1].text):
            tds[3]["class"] = "custom"
         if int(tds[2].text) < int(tds[1].text):
            tds[2]["class"] = "custom"
    

    使用你的输入 html 会给你:

    <html><body><table border="1" class="dataframe">
    <thead>
    <tr style="text-align: right;">
    <th>name</th>
    <th>threshold</th>
    <th>col1</th>
    <th>col2</th>
    <th>col3</th>
    </tr>
    </thead>
    <tbody>
    <tr>
    <td>A</td>
    <td>10</td>
    <td>12</td>
    <td class="custom">9</td>
    <td>13</td>
    </tr>
    <tr>
    <td>B</td>
    <td>15</td>
    <td>18</td>
    <td>17</td>
    <td>23</td>
    </tr>
    <tr>
    <td>C</td>
    <td>20</td>
    <td class="custom">19</td>
    <td>22</td>
    <td>25</td>
    </tr>
    </tbody>
    </table></body></html>
    

    只需使用 if 中的任何内容来决定是否添加它。

    【讨论】:

    • 在我的例子中, df.to_html() 返回一个 unicode 类型,因为我的 df 是一个数据框。然后我不能在 Beautiful Soup 函数中使用“html.parser”。我上面提到的标准是,如果该值小于该行的阈值列中的值,则添加“自定义”类,否则什么也不做,继续下一个。
    • 使用 BeautifulSoup(html, "html.parser") 时出现错误:AttributeError: 'str' object has no attribute 'text'。就我而言,html 是 unicode 类型,它来自: html = pd.read_csv("data.csv").to_html(index=False)
    • 您做错了什么,因为 td 永远不可能是文本。什么是完整的回溯?
    • 似乎是“html.parser”引起了这个问题,如果我只做BeautifulSoup(html),那就没问题
    • 所以你也安装了lxml?它对我来说很好,所以不知道为什么 html.parser 让你窒息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-06
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    • 2018-07-31
    • 2021-03-27
    相关资源
    最近更新 更多