长期使用,但从来没有问过我自己的问题.

我想使用Python将一个表从一个html文档解析成一个数据帧.该表不是html表,我认为它是由javascript创建的html,它只是使用一堆带有奇怪命名的类的div来创建格式和布局.

这些数据是工人及其工作时间,按工作区域排序.问题是,div不是嵌套的,因此我不能轻松地 for each 工人分配他们的工作区.我用的是美味的汤.

下面是一个简化的示例:

<html>
<body>
<div class="workarea">construction
</div>
  <div class="name">Anna
  </div>
  <div class="Muell">w23f84md2o
  </div>
  <div class="time">8:23
  </div>
    <div class="name">Tom
  </div>
  <div class="Muell">w23f84md2o
  </div>
  <div class="time">10:20
  </div>
 <div class="workarea">cleaning
</div>
  <div class="name">Max
  </div>
  <div class="Muell">w23f84md2o
  </div>
  <div class="time">9:30
  </div>
</body>
</html>

以下是我想要的数据框:

WORKAREA NAME TIME
construction Anna 8:23
construction Tom 10:20
cleaning Max 9:30

注意:真正的数据有数千个div用于格式化和布局,这就是为什么我想使用适当的解析器,而不是将文档逐行读取到python中,然后自己解析它.

我没走多远:

### read html with bs4
with open("testdoc1.html") as fp:
     soup=BeautifulSoup(fp,"html.parser")

wa = soup.find_all("div",class="workarea")
## here I wanted to add a for loop through wa, but wa doesnt actually contain the info

我不能遍历wa来获取细节,因为它只包含构造和清理div,没有介于两者之间的内容.

有没有一个解决方案来解析逐行但实际上是逐div的?

我可以让find_all查找所有具有as类workarea,time or name的div吗?并保持他们的阅读顺序?

我知道已经有很多关于beautifulsoup和解析html文档的stackoverflow问题,但我真的找不到解决方案,因为原始表实际上并不只是一个表,可悲的是,html中没有保留层次 struct .

非常感谢你的帮助!如有任何提示,不胜感激!

推荐答案

try :

import pandas as pd
from bs4 import BeautifulSoup

html_text = """\
<html>
<body>
<div class="workarea">construction
</div>
  <div class="name">Anna
  </div>
  <div class="Muell">w23f84md2o
  </div>
  <div class="time">8:23
  </div>
    <div class="name">Tom
  </div>
  <div class="Muell">w23f84md2o
  </div>
  <div class="time">10:20
  </div>
 <div class="workarea">cleaning
</div>
  <div class="name">Max
  </div>
  <div class="Muell">w23f84md2o
  </div>
  <div class="time">9:30
  </div>
</body>
</html>"""

soup = BeautifulSoup(html_text, "html.parser")

data = []
for name in soup.select(".name"):
    workarea = name.find_previous(class_="workarea")
    data.append(
        {
            "workarea": workarea.text.strip(),
            "name": name.text.strip(),
            "time": name.find_next(class_="time").text.strip(),
        }
    )

df = pd.DataFrame(data)
print(df)

打印:

       workarea  name   time
0  construction  Anna   8:23
1  construction   Tom  10:20
2      cleaning   Max   9:30

Python相关问答推荐

如何根据日期和时间将状态更新为已过期或活动?

运行回文查找器代码时发生错误:[类型错误:builtin_index_or_system对象不可订阅]

Django管理面板显示字段最大长度而不是字段名称

如何在Django基于类的视图中有效地使用UTE和RST HTIP方法?

django禁止直接分配到多对多集合的前端.使用user.set()

Godot:需要碰撞的对象的AdditionerBody2D或Area2D以及queue_free?

avxspan与pandas period_range

连接一个rabrame和另一个1d rabrame不是问题,但当使用[...]'运算符会产生不同的结果

什么是最好的方法来切割一个相框到一个面具的第一个实例?

Python导入某些库时非法指令(核心转储)(beautifulsoup4."" yfinance)

在Python中使用if else或使用regex将二进制数据如111转换为001""

寻找Regex模式返回与我当前函数类似的结果

如何在Great Table中处理inf和nans

Python日志(log)模块如何在将消息发送到父日志(log)记录器之前向消息添加类实例变量

在用于Python的Bokeh包中设置按钮的样式

语法错误:文档. evaluate:表达式不是合法表达式

如何在SQLAlchemy + Alembic中定义一个"Index()",在基表中的列上

删除Dataframe中的第一个空白行并重新索引列

将Pandas DataFrame中的列名的长文本打断/换行为_STRING输出?

合并Pandas中的数据帧,但处理不存在的列