【问题标题】:Extract data from html to csv using BeautifulSoup使用 BeautifulSoup 将数据从 html 提取到 csv
【发布时间】:2017-08-14 13:31:22
【问题描述】:

我想从天气站点中提取数据并将其复制到 csv 文件中以供进一步分析。我正在使用 python 和 BeautifulSoup。我一直在努力从天气报告和数值中获取受影响的城市。 Hier 是 HTML 的样子:

> <html>  <head>   <meta charset="utf-8"/>  </head>  <body>   <div
> id="main">    <div id="wettertab">
>     <p>
>      <strong>
>       Letzte Aktualisierung: Do, 10. Aug, 18:41 Uhr
>      </strong>
>     </p>
>     <h1 id="Hessen">
>      Hessen
>     </h1>
>     <h2 id="Gemeinde Aarbergen">
>      Gemeinde Aarbergen
>     </h2>
>     <table>
>      <colgroup>
>       <col <="" class="firstColumn" col=""/>
>       <col class="colorColumn"/>
>       <col class="colorColumn"/>
>       <col class="colorColumn"/>
>       <thead>
>        <tr>
>         <th>
>          Schlagzeile
>         </th>
>         <th>
>          Gültig von
>         </th>
>         <th>
>          Gültig bis
>         </th>
>         <th>
>          Beschreibung
>         </th>
>        </tr>
>       </thead>
>       <tr>
>        <td>
>         Amtliche WARNUNG vor DAUERREGEN
>        </td>
>        <td>
>         Do, 10. Aug, 12:00 Uhr
>        </td>
>        <td>
>         Sa, 12. Aug, 06:00 Uhr
>        </td>
>        <td>
>         Es tritt Dauerregen mit Unterbrechungen auf. Dabei werden Niederschlagsmengen zwischen 40 l/m² und 60 l/m² erwartet.
>        </td>
>       </tr>
>      </colgroup>
>     </table>

我需要表格中的四个值:

<tr> 
<td> Amtliche WARNUNG vor DAUERREGEN 
</td> 
<td> Do, 10. Aug, 12:00 Uhr 
</td> 
<td> Sa, 12. Aug, 06:00 Uhr 
</td> 
<td> Es tritt Dauerregen mit Unterbrechungen auf. Dabei werden Niederschlagsmengen zwischen 40 l/m² und 60 l/m² erwartet. 
</td> 
</tr>

我还需要地点的名称:

<h2 id="Gemeinde Aarbergen">
 Gemeinde Aarbergen
</h2>

“h2”的 HTML 标记总是在表格之前,但它不属于表格本身,正如我所见。

到目前为止,这是我的代码 sn-p:

from urllib.request import urlopen
from bs4 import BeautifulSoup

html = urlopen("html_warnung.html")
soup = BeautifulSoup(html, 'html.parser')

table = soup.findAll("table")
for div in table:
    row = ''
    rows = div.findAll('td')

    for row in rows:
        print(row.text)

现在我可以打印表格中的值,还可以通过以下方式获取城市名称:

gemeinde_list = []
for gemeinde in soup.findAll('h2'):
    gemeinde_list.append(gemeinde.get("id"))

将所有信息一起导出到 csv 文件以便获得分隔值的最佳方法是什么:

Gemeinde Aarbergen
Amtliche WARNUNG vor DAUERREGEN
做,8 月 10 日,12:00 Uhr
萨,8 月 12 日,06:00 Uhr
Es tritt Dauerregen wechselnder Intensität auf。 Dabei werden Niederschlagsmengen zwischen 35 l/m² 和 50 l/m² erwartet。在 Staulagen werden Mengen bis 70 l/m² erreicht。

我正在使用 Python 3.6 请帮忙。

【问题讨论】:

  • 可以使用Python自带的csv模块。
  • 嗨 Mekicha,是的,我想困难的部分是如何将 html 文件中的值放在一起,当我把它们放在一起时,可能是一个列表,我想我可以存储它们在 csv 中。我目前的问题是所描述的价值观。

标签: python beautifulsoup


【解决方案1】:

由于表格或标题都没有任何特征属性,您可以使用find_next_siblings / find_previous_siblings 方法获取相邻标签。

tables = soup.find_all('table')
data = []
for table in tables: 
    previous = table.find_previous_siblings('h2') 
    id = previous[0].get('id') if previous else None
    rows = [td.get_text(strip=True) for td in table.find_all('td')]
    data.append([id] + rows)

data 变量是一个嵌套列表,您现在可以将其写入 csv。

with open('my_file.csv', 'wb') as f:
    writer = csv.writer(f)
    writer.writerows(data)

【讨论】:

  • 看起来整个东西都在一个 div 中。因此,如果您在每个页面上有多个这样的元素,请将主要元素设为 div-tag。因此,您需要做的所有事情 - 对于每个 div - 就是从第二个 tr 中的 tds 中获取 .h2 和所有 .text。
  • @jlaur 我们不知道 html 的确切结构,所以我尝试了一个更通用的解决方案:“查找所有表和以前的 'h2'”。但是,您的想法:“查找包含至少一个 'h2' 和 'table' 的所有 div”可能同样有效,甚至更好。不错!
  • @t.m.adam: 完成了这项工作,非常优雅。谢谢。每个页面只有一个div,html代码其实很简单,只有一个div,很多table。
  • 我知道a有一个列表。如何将列表的第一项与其他文件中的其他列表进行比较??
  • 您可以使用[i[0] for i in data] 选择data 中所有列表的第一项。如果您想从文件中读取data 列表,请使用:with open('my_file.csv', 'rb') as f: data = list(csv.reader(f))
【解决方案2】:

您可以将要保存在 csv 行中的数据放入元组中。基本上,在提取它们时将它们分配给一个变量并将它们全部放入一个元组中。 我不完全理解您要提取的数据的结构。

但我猜:

city_name = "Gemeinde Aarbergen"
start_date = "Do, 10. Aug, 12:00 Uhr"
end_date = "Sa, 12. Aug, 06:00 Uhr"
desc = "Es tritt Dauerregen wechselnder Intensität auf. Dabei werden Niederschlagsmengen zwischen 35 l/m² und 50 l/m² erwartet. In Staulagen werden Mengen bis 70 l/m² erreicht."

正如我所说,我不知道这些字段是什么。你可以更好地命名它们。 然后你将拥有:

import csv
csv_row = (city_name, start_date, end_date, desc)
with open(filename, "wb") as csv_file:
    writer = csv.writer(csv_file, delimiter=',')
    writer.writerow(csv_row)

希望这是有道理的。

【讨论】:

  • 结构正确。我的问题是如何从 html 中提取该格式的数据。正如您在上面的 HTML 示例中看到的,城市的名称

    在表格之外,我不知道将城市与每个表格匹配。

  • 提取城市并将其保存为city_name,然后解析表并提取您需要的其他变量,同时保存它们。然后创建元组。还是行重复?意思是,例如每个城市名称都有不止一个表?
  • 您可以检查是否有一个 div 包含每个天气条目的 h2 和表格,或者您可以查看每个表格是否有一个 h2 元素。您可以 findAll h2tables 。在这种情况下,您会得到两个列表,用于 h2 和表。您可以遍历两者以创建元组或使用zip。如果这没有帮助,请告诉我
猜你喜欢
  • 1970-01-01
  • 2013-01-29
  • 2019-06-02
  • 2015-09-29
  • 2019-05-24
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 2015-01-21
相关资源
最近更新 更多