基于一个包含统计信息的网站,我实现了基本的Web抓取代码,如下所示:

import re
import requests
from bs4 import BeautifulSoup
content = requests.get("https://www.geostat.ge/ka/modules/categories/26/samomkhmareblo-fasebis-indeksi-inflatsia")
content = BeautifulSoup(content.content, 'html.parser')
#print(content.prettify())
information = []
for row in content.select('tbody tr'):
    for data in row.find_all('td'):
        if len(data.text.strip()) != 0:
            information.append(data.text.strip())
print(information)

它返回以下信息:

['2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021', '2022', '2023', 'საშუალო წლიური წინა წლის საშუალო წლიურთან', '99.1', '99.5', '103.1', '104.0', '102.1', '106.0', '102.6', '104.9', '105.2', '109.6', '111.9', '102.5', 'დეკემბერი წინა წლის დეკემბერთან', '98.6', '102.4', '102.0', '104.9', '101.8', '106.7', '101.5', '107.0', '102.4', '113.9', '109.8', '100.4'

现在文本前面的第一部分包含‘საშუალო’年份,其余部分是两个文本之间的通货inflating ,所以我实现了这个非常手动的代码:

years = []
average_annual = []
december = []

first_index = information.index('საშუალო წლიური წინა წლის საშუალო წლიურთან')
second_index = information.index('დეკემბერი წინა წლის დეკემბერთან')
for i in range(0, first_index):
    years.append(int(information[i]))
print(years)
for  i in range(first_index + 1, second_index):
    average_annual.append(float(information[i]))
print(average_annual)
for i in range(second_index + 1, len(information)):
    december.append(float(information[i]))
print(december)

它显示了正确的分隔:

[2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023]
[99.1, 99.5, 103.1, 104.0, 102.1, 106.0, 102.6, 104.9, 105.2, 109.6, 111.9, 102.5]
[98.6, 102.4, 102.0, 104.9, 101.8, 106.7, 101.5, 107.0, 102.4, 113.9, 109.8, 100.4]

有没有更好的方法来做到这一点?

我试过这个版本:

data = pd.DataFrame(pd.read_html("https://www.geostat.ge/ka/modules/categories/26/samomkhmareblo-fasebis-indeksi-inflatsia", encoding='utf-8')[0])
#data.drop(0, axis=0, inplace=True)
#data = data.droplevel(level=0, axis=1)
print(data)

并返回以下结果:

                                          0       1   ...      11      12
0                                        NaN  2012.0  ...  2022.0  2023.0
1  საშუალო წლიური წინა წლის საშუალო წლიურთან    99.1  ...   111.9   102.5
2            დეკემბერი წინა წლის დეკემბერთან    98.6  ...   109.8   100.4

[3 rows x 13 columns]

我该怎么处理这个案子呢?

推荐答案

对于这个站点,我建议使用pandas.read_html将表读入数据帧.但首先,您可以将第一行重命名为Header(<th>),以获得正确的列名:

from io import StringIO

import pandas as pd
import requests
from bs4 import BeautifulSoup

url = '"https://www.geostat.ge/ka/modules/categories/26/samomkhmareblo-fasebis-indeksi-inflatsia"'
content = requests.get(url).content
soup = BeautifulSoup(content, "html.parser")

for td in soup.tr.select("td"):
    td.name = "th"

df = pd.read_html(StringIO(str(soup)))[0]
df = df.set_index(df.columns[0])
df.index.name = None

print(df)

打印:

                                           2012   2013   2014   2015   2016   2017   2018   2019   2020   2021   2022   2023
საშუალო წლიური წინა წლის საშუალო წლიურთან  99.1   99.5  103.1  104.0  102.1  106.0  102.6  104.9  105.2  109.6  111.9  102.5
დეკემბერი წინა წლის დეკემბერთან            98.6  102.4  102.0  104.9  101.8  106.7  101.5  107.0  102.4  113.9  109.8  100.4

Python相关问答推荐

使用FASTCGI在IIS上运行Django频道

为什么tkinter框架没有被隐藏?

按列分区,按另一列排序

对所有子图应用相同的轴格式

运输问题分支定界法&

在np数组上实现无重叠的二维滑动窗口

使用NeuralProphet绘制置信区间时出错

合并帧,但不按合并键排序

在不同的帧B中判断帧A中的子字符串,每个帧的大小不同

合并与拼接并举

基于另一列的GROUP-BY聚合将列添加到Polars LazyFrame

30个非DATETIME天内的累计金额

用0填充没有覆盖范围的垃圾箱

EST格式的Azure数据库笔记本中的当前时间戳

某些值的数值幂和**之间的差异

使用美汤对维基百科表格进行网络刮擦未返回任何内容

我可以同时更改多个图像吗?

来自任务调度程序的作为系统的Python文件

ValueError:必须在Pandas 中生成聚合值

Django查询集-排除True值