python - 将多个 div 类中的数据抓取到 pandas 数据框中
问题描述
我正在从仪表板上刮掉一些数据,并试图将多个数据中的一些数据div classes
放入熊猫数据框中。我应该如何尝试转换这样的东西:
[<div class="map-item" data-companyname="Apical Group" data-country="INDONESIA" data-district="Jakarta Utara" data-latitude="-6.099396000" data-longitude="106.951478000" data-millname="AAJ Marunda" data-province="Jakarta" data-report="http://naturalhealthytreat.com/sites/neste-daemeter.com/files/AAJ_Marunda.pdf" id="map_item_4645">AAJ Marunda</div>,
<div class="map-item" data-companyname="Apical Group" data-country="INDONESIA" data-district="Lubuk Gaung" data-latitude="1.754005000" data-longitude="101.363532000" data-millname="Sari Dumai Sejati" data-province="Riau" data-report="http://naturalhealthytreat.com/sites/neste-daemeter.com/files/Sari_Dumai_Sejati.pdf" id="map_item_4646">Sari Dumai Sejati</div>,
<div class="map-item" data-companyname="Kutai Refinery Nusantara " data-country="INDONESIA" data-district="Balikpapan" data-latitude="-1.179099000" data-longitude="116.788274000" data-millname="Kutai Refinery Nusantara " data-province="Penajam Paser Utara" data-report="http://naturalhealthytreat.com/sites/neste-daemeter.com/files/Kutai_Refinery_Nusantara_.pdf" id="map_item_4647">Kutai Refinery Nusantara </div>]
进入这样的数据框:
no companyname country district latitude longitude millname province report
1 Apical Group INDONESIA Jakarta Utara -6.099396 106.951478 AAJ Marunda Jakarta http://naturalhealthytreat.com/sites/neste-daemeter.com/files/AAJ_Marunda.pdf
2 Apical Group INDONESIA Lubuk Gaung 1.754005 101.363532 Sari Dumai Sejati Riau http://naturalhealthytreat.com/sites/neste-daemeter.com/files/Kutai_Refinery_Nusantara_.pdf
3 Kutai Refinery Nusantara INDONESIA Balikpapan -1.179099 116.788274 Kutai Refinery Nusantara Penajam Paser Utara http://naturalhealthytreat.com/sites/neste-daemeter.com/files/Kutai_Refinery_Nusantara_.pdf
到目前为止,这是我为从网页获取多个 div 类而编写的代码:
from bs4 import BeautifulSoup
import requests
# Link of Neste dashboard
url = 'http://nestetraceabilitydashboard.com/nestes-pfad-traceability-dashboard'
page = requests.get(url).content
soup = BeautifulSoup(page, "html.parser")
divList = soup.findAll('div', attrs={ "class" : "map-item"})
解决方案
我们可以通过属性访问标签的.attrs
属性。所以我们可以创建一个包含所有标签属性(除了class和id)的字典,并将它传递给一个数据框。
from bs4 import BeautifulSoup
import requests
import pandas as pd
url = 'http://nestetraceabilitydashboard.com/nestes-pfad-traceability-dashboard'
page = requests.get(url).text
soup = BeautifulSoup(page, "html.parser")
divList = soup.findAll('div', attrs={"class" : "map-item"})
data = {}
for div in divList:
for k,v in div.attrs.items():
if k not in ('class', 'id'):
k = k.split('-')[1]
data[k] = data.get(k, []) + [v]
df = pd.DataFrame(data)
print(df.head(3))
数据框:
companyname country district latitude \
0 Apical Group INDONESIA Jakarta Utara -6.099396000
1 Apical Group INDONESIA Lubuk Gaung 1.754005000
2 Kutai Refinery Nusantara INDONESIA Balikpapan -1.179099000
longitude millname province \
0 106.951478000 AAJ Marunda Jakarta
1 101.363532000 Sari Dumai Sejati Riau
2 116.788274000 Kutai Refinery Nusantara Penajam Paser Utara
report
0 http://naturalhealthytreat.com/sites/neste-dae...
1 http://naturalhealthytreat.com/sites/neste-dae...
2 http://naturalhealthytreat.com/sites/neste-dae...
关于的建议requests
最好使用.text
而不是.content
,因为它保存解码后的响应内容(文本)。所以总是使用.text
,除非响应 a 是二进制文件(图像、pdf 等)。
关于BeautifulSoup
findAll
用于向后兼容bs3
,bs4
因为它被重命名为find_all
. 此外,您可以使用属性作为关键字参数,例如:
find_all('div', class_="map-item")
这里我使用class_
类属性,因为class
它是一个 Python 关键字,但对于其他属性(id、href 等),您可以按原样使用它们的名称。
推荐阅读
- outlook - 如何在 Outlook Web 加载项中发送附件大小 > 1MB 的电子邮件?
- google-sheets - 当光标选择Google表格中的当前单元格时如何获取列/行号
- php - TYPO3:带有参数和依赖注入的 Symfony 命令
- windows - 如何读取 .txt 文件中的文本及其在 powershell 中的每个值?
- javascript - 如何设置计划以在特定时间运行特定文件?
- php - 对数组元素进行分组并计算价格
- css - 标题不填充 IE 10 中的包装器元素
- c# - 从 WebApi 中的 HttpRequestMessage.Content 检索的流中检索数据
- oracle - 存储过程中的 Oracle 搜索
- java - List 类型中的方法 get(int)
不适用于 Java 8 中的参数字符串