python - BeautifulSoup 从多个表中提取数据

标签 python html beautifulsoup

我正在尝试从 html file 中的两个 html 表中提取一些数据与 BeautifulSoup。

这实际上是我第一次使用它,我搜索了很多问题/示例,但似乎没有一个适用于我的情况。 html 包含两个表,第一个包含第一列的标题(始终为文本),第二个包含以下各列的数据。此外,表格包含文本、数字和符号。这使得像我这样的新手一切都变得更加复杂。 Here's从浏览器复制的 html 布局 我能够提取行的整个 html 内容,但只能提取第一个表,所以实际上我没有得到任何数据,只有第一列的内容。

我试图获得的输出是一个字符串,其中包含表格的“联合”信息(Col1=文本、Col2=数字、Col3=数字、Col4=数字、Col5=数字),例如:

Canada, 6, 5, 2, 1

这是每个项目的 Xpath 列表:

"Canada": /html/body/div/div[1]/table/tbody[2]/tr[2]/td/div/a
"6": /html/body/div/div[2]/div/table/tbody[2]/tr[2]/td[1] 
"5": /html/body/div/div[2]/div/table/tbody[2]/tr[2]/td[3] 
"2": /html/body/div/div[2]/div/table/tbody[2]/tr[2]/td[5]
"1": /html/body/div/div[2]/div/table/tbody[2]/tr[2]/td[7]

我对“粗略”html 格式的字符串也很满意,只要每行有一个字符串,这样我就可以用我已经知道的方法进一步解析它。这是我到目前为止的代码。谢谢!

from BeautifulSoup import BeautifulSoup
html=""" 
my html code
"""
soup = BeautifulSoup(html)
table=soup.find("table")
for row in table.findAll('tr'):
    col = row.findAll('td')
    print row, col

最佳答案

使用 bs4,但这应该可行:

from bs4 import BeautifulSoup as bsoup

ofile = open("htmlsample.html")
soup = bsoup(ofile)
soup.prettify()

tables = soup.find_all("tbody")

storeTable = tables[0].find_all("tr")
storeValueRows = tables[2].find_all("tr")

storeRank = []
for row in storeTable:
    storeRank.append(row.get_text().strip())

storeMatrix = []
for row in storeValueRows:
    storeMatrixRow = []
    for cell in row.find_all("td")[::2]:
        storeMatrixRow.append(cell.get_text().strip())
    storeMatrix.append(", ".join(storeMatrixRow))

for record in zip(storeRank, storeMatrix):
    print " ".join(record)

上面会打印出:

# of countries - rank 1 reached 0, 0, 1, 9
# of countries - rank 5 reached 0, 8, 49, 29
# of countries - rank 10 reached 25, 31, 49, 32
# of countries - rank 100 reached 49, 49, 49, 32
# of countries - rank 500 reached 49, 49, 49, 32
# of countries - rank 1000 reached 49, 49, 49, 32
[Finished in 0.5s]

storeTable 更改为 tables[1] 并将 storeValueRows 更改为 tables[3] 将打印出:

Country 
Canada 6, 5, 2, 1
Brazil 7, 5, 2, 1
Hungary 7, 6, 2, 2
Sweden 9, 5, 1, 1
Malaysia 10, 5, 2, 1
Mexico 10, 5, 2, 2
Greece 10, 6, 2, 1
Israel 10, 6, 2, 1
Bulgaria 10, 6, 2, -
Chile 10, 6, 2, -
Vietnam 10, 6, 2, -
Ireland 10, 6, 2, -
Kuwait 10, 6, 2, -
Finland 10, 7, 2, -
United Arab Emirates 10, 7, 2, -
Argentina 10, 7, 2, -
Slovakia 10, 7, 2, -
Romania 10, 8, 2, -
Belgium 10, 9, 2, 3
New Zealand 10, 13, 2, -
Portugal 10, 14, 2, -
Indonesia 10, 14, 2, -
South Africa 10, 15, 2, -
Ukraine 10, 15, 2, -
Philippines 10, 16, 2, -
United Kingdom 11, 5, 2, 1
Denmark 11, 6, 2, 2
Australia 12, 9, 2, 3
United States 13, 9, 2, 2
Austria 13, 9, 2, 3
Turkey 14, 5, 2, 1
Egypt 14, 5, 2, 1
Netherlands 14, 8, 2, 2
Spain 14, 11, 2, 4
Thailand 15, 10, 2, 3
Singapore 16, 10, 2, 2
Switzerland 16, 10, 2, 3
Taiwan 17, 12, 2, 4
Poland 17, 13, 2, 5
France 18, 8, 2, 3
Czech Republic 18, 13, 2, 6
Germany 19, 11, 2, 3
Norway 20, 14, 2, 5
India 20, 14, 2, 5
Italy 20, 15, 2, 7
Hong Kong 26, 21, 2, -
Japan 33, 16, 4, 5
Russia 33, 17, 2, 7
South Korea 46, 27, 2, 5
[Finished in 0.6s]

不是最好的代码,可以进一步改进。然而,这个逻辑很适用。

希望这对您有所帮助。

编辑:

如果您想要格式 South Korea, 46, 27, 2, 5 而不是 South Korea 46, 27, 2, 5 (注意 , 在国家名称之后),只需更改此:

storeRank.append(row.get_text().strip())

为此:

storeRank.append(row.get_text().strip() + ",")

关于python - BeautifulSoup 从多个表中提取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22410416/

相关文章:

python - Pandas - 将多个组行合并为一行

c# - 使用两个 Redis 实例 - 类似于 Mongos

javascript - ZK中如何防止拖拽所有组件上的文本

html - 菜单链接不向右浮动

python - django manage.py 设置默认

html - 为什么相同样式的 div 和按钮呈现不同的尺寸?

python - 使用 Mechanize bing 搜索返回空白页

python - 如何使用变量设置 Discord 嵌入消息的图像?

python - 字典键与值匹配时遇到问题

python - Pandas:将填充有下拉菜单的 Excel 列拆分为多个数据框列并隔离拼写错误