如何使用 Python 中的 BeautifulSoup 从 HTML link 解析嵌套的 table?
How to parse nested table from HTML link using BeautifulSoup in Python?
全部,
我正在尝试从这个 link http://web1.ncaa.org/stats/StatsSrv/careersearch 中解析 table。
请注意:要在 "School/Sport Search" select All for School, Year -2005-2006, Sport -Football, Division I 下搜索。我要解析的列是学校名称,如果您单击学校Name.More信息会输出。从那个 link/Table 我想为每一所学校解析 "Stadium Capacity"。我的问题是这样的事情可能吗?如果是,怎么办?我是 python 和 BeautifulSoup 的新手,如果你能提供解释那就太好了!
注:共有239条结果,
总结一下:所以基本上我想解析学校名称及其体育场容量并将其转换为 Pandas 数据框
import requests
from bs4 import BeautifulSoup
URL = "http://web1.ncaa.org/stats/StatsSrv/careerteam"
r = requests.get(URL)
soup = BeautifulSoup(r.content, 'html5lib')
print(soup.prettify())
My question is Is something like this possible ?
是的。
If yes,how ?
下面的代码中有很多内容。但要点是弄清楚浏览器发出的 post 请求,然后使用 Requests 模拟它。我们可以通过检查工具中的“网络”选项卡找到正在发出的请求。
首先我们发出 'search' post 请求。这给出了左和右table。点击左边的 table 可以看到该地区的学校。但是如果我们仔细观察点击区域 link 也是一个 post 请求(我们必须使用 requests 来完成)
例如。单击 'Air Force - Eastern Ill.' 会给我们一个 table,其中包含该地区的 link 所学校。那我们得去那所学校link算一下容量。
因为点击每个学校 link 也是一个 post 请求,我们必须模拟这个 returns 学校页面。我们从这里抓取学校名称和容量。
您可以阅读 Advanced Usage of requests to know about Session objects, Making a request 了解如何使用 Requests 提出请求。
import requests
from bs4 import BeautifulSoup
import pandas as pd
end_list=[]
s = requests.Session()
URL = "http://web1.ncaa.org/stats/StatsSrv/careersearch"
data={'doWhat': 'teamSearch','searchOrg': 'X', 'academicYear': 2006, 'searchSport':'MFB','searchDiv': 1}
r = s.post(URL,data=data)
soup=BeautifulSoup(r.text,'html.parser')
area_list=soup.find_all('table')[8].find_all('tr')
area_count=len(area_list)#has no of areas + 1 tr 'Total Results of Search: 239'
for idx in range(0,area_count):
data={
'sortOn': 0,
'doWhat': 'showIdx',
'playerId':'' ,'coachId': '',
'orgId':'' ,
'academicYear':'' ,
'division':'' ,
'sportCode':'' ,
'idx': idx
}
r = s.post(URL,data=data)
soup=BeautifulSoup(r.text,'html.parser')
last_table=soup.find_all('table')[-1]#last table
for tr in last_table.find_all('tr'):
link_td=tr.find('td',class_="text")
try:
link_a=link_td.find('a')['href']
data_params=link_a.split('(')[1][:-2].split(',')
try:
#print(data_params)
sports_code=data_params[2].replace("'","").strip()
division=int(data_params[3])
player_coach_id=int(data_params[0])
academic_year=int(data_params[1])
org_id=int(data_params[4])
#print(sports_code,division,player_coach_id,academic_year,org_id)
data={
'sortOn': 0,
'doWhat': 'display',
'playerId': player_coach_id,
'coachId': player_coach_id,
'orgId': org_id,
'academicYear': academic_year,
'division':division,
'sportCode':sports_code,
'idx':''
}
url='http://web1.ncaa.org/stats/StatsSrv/careerteam'
r = s.post(url,data=data)
soup2=BeautifulSoup(r.text,'html.parser')
institution_name=soup2.find_all('table')[1].find_all('tr')[2].find_all('td')[1].text.strip()
capacity=soup2.find_all('table')[4].find_all('tr')[2].find_all('td')[1].text.strip()
#print([institution_name, capacity])
end_list.append([institution_name, capacity])
except IndexError:
pass
except AttributeError:
pass
#print(end_list)
headers=['School','Capacity']
df=pd.DataFrame(end_list, columns=headers)
print(df)
输出
School Capacity
0 Air Force 46,692
1 Akron 30,000
2 Alabama 101,821
3 Alabama A&M; 21,000
4 Alabama St. 26,500
5 Albany (NY) 8,500
6 Alcorn 22,500
7 Appalachian St. 30,000
8 Arizona 55,675
9 Arizona St. 64,248
10 Ark.-Pine Bluff 14,500
11 Arkansas 72,000
12 Arkansas St. 30,708
13 Army West Point 38,000
14 Auburn 87,451
15 Austin Peay 10,000
16 BYU 63,470
17 Ball St. 22,500
18 Baylor 45,140
19 Bethune-Cookman 9,601
20 Boise St. 36,387
21 Boston College 44,500
22 Bowling Green 24,000
23 Brown 20,000
24 Bucknell 13,100
25 Buffalo 29,013
26 Butler 5,647
27 Cal Poly 11,075
28 California 62,467
29 Central Conn. St. 5,500
.. ... ...
209 UCLA 91,136
210 UConn 40,000
211 UNI 16,324
212 UNLV 36,800
213 UT Martin 7,500
214 UTEP 52,000
215 Utah 45,807
216 Utah St. 25,100
217 VMI 10,000
218 Valparaiso 5,000
219 Vanderbilt 40,350
220 Villanova 12,000
221 Virginia 61,500
222 Virginia Tech 65,632
223 Wagner 3,300
224 Wake Forest 31,500
225 Washington 70,138
226 Washington St. 32,740
227 Weber St. 17,500
228 West Virginia 60,000
229 Western Caro. 13,742
230 Western Ill. 16,368
231 Western Ky. 22,113
232 Western Mich. 30,200
233 William & Mary 12,400
234 Wisconsin 80,321
235 Wofford 13,000
236 Wyoming 29,181
237 Yale 64,269
238 Youngstown St. 20,630
[239 rows x 2 columns]
注意:
这将需要很长时间。我们正在 抓取 >239 页。所以请耐心等待。可能需要 15 分钟或更长时间。
全部,
我正在尝试从这个 link http://web1.ncaa.org/stats/StatsSrv/careersearch 中解析 table。 请注意:要在 "School/Sport Search" select All for School, Year -2005-2006, Sport -Football, Division I 下搜索。我要解析的列是学校名称,如果您单击学校Name.More信息会输出。从那个 link/Table 我想为每一所学校解析 "Stadium Capacity"。我的问题是这样的事情可能吗?如果是,怎么办?我是 python 和 BeautifulSoup 的新手,如果你能提供解释那就太好了!
注:共有239条结果,
总结一下:所以基本上我想解析学校名称及其体育场容量并将其转换为 Pandas 数据框
import requests
from bs4 import BeautifulSoup
URL = "http://web1.ncaa.org/stats/StatsSrv/careerteam"
r = requests.get(URL)
soup = BeautifulSoup(r.content, 'html5lib')
print(soup.prettify())
My question is Is something like this possible ?
是的。
If yes,how ?
下面的代码中有很多内容。但要点是弄清楚浏览器发出的 post 请求,然后使用 Requests 模拟它。我们可以通过检查工具中的“网络”选项卡找到正在发出的请求。
首先我们发出 'search' post 请求。这给出了左和右table。点击左边的 table 可以看到该地区的学校。但是如果我们仔细观察点击区域 link 也是一个 post 请求(我们必须使用 requests 来完成)
例如。单击 'Air Force - Eastern Ill.' 会给我们一个 table,其中包含该地区的 link 所学校。那我们得去那所学校link算一下容量。
因为点击每个学校 link 也是一个 post 请求,我们必须模拟这个 returns 学校页面。我们从这里抓取学校名称和容量。
您可以阅读 Advanced Usage of requests to know about Session objects, Making a request 了解如何使用 Requests 提出请求。
import requests
from bs4 import BeautifulSoup
import pandas as pd
end_list=[]
s = requests.Session()
URL = "http://web1.ncaa.org/stats/StatsSrv/careersearch"
data={'doWhat': 'teamSearch','searchOrg': 'X', 'academicYear': 2006, 'searchSport':'MFB','searchDiv': 1}
r = s.post(URL,data=data)
soup=BeautifulSoup(r.text,'html.parser')
area_list=soup.find_all('table')[8].find_all('tr')
area_count=len(area_list)#has no of areas + 1 tr 'Total Results of Search: 239'
for idx in range(0,area_count):
data={
'sortOn': 0,
'doWhat': 'showIdx',
'playerId':'' ,'coachId': '',
'orgId':'' ,
'academicYear':'' ,
'division':'' ,
'sportCode':'' ,
'idx': idx
}
r = s.post(URL,data=data)
soup=BeautifulSoup(r.text,'html.parser')
last_table=soup.find_all('table')[-1]#last table
for tr in last_table.find_all('tr'):
link_td=tr.find('td',class_="text")
try:
link_a=link_td.find('a')['href']
data_params=link_a.split('(')[1][:-2].split(',')
try:
#print(data_params)
sports_code=data_params[2].replace("'","").strip()
division=int(data_params[3])
player_coach_id=int(data_params[0])
academic_year=int(data_params[1])
org_id=int(data_params[4])
#print(sports_code,division,player_coach_id,academic_year,org_id)
data={
'sortOn': 0,
'doWhat': 'display',
'playerId': player_coach_id,
'coachId': player_coach_id,
'orgId': org_id,
'academicYear': academic_year,
'division':division,
'sportCode':sports_code,
'idx':''
}
url='http://web1.ncaa.org/stats/StatsSrv/careerteam'
r = s.post(url,data=data)
soup2=BeautifulSoup(r.text,'html.parser')
institution_name=soup2.find_all('table')[1].find_all('tr')[2].find_all('td')[1].text.strip()
capacity=soup2.find_all('table')[4].find_all('tr')[2].find_all('td')[1].text.strip()
#print([institution_name, capacity])
end_list.append([institution_name, capacity])
except IndexError:
pass
except AttributeError:
pass
#print(end_list)
headers=['School','Capacity']
df=pd.DataFrame(end_list, columns=headers)
print(df)
输出
School Capacity
0 Air Force 46,692
1 Akron 30,000
2 Alabama 101,821
3 Alabama A&M; 21,000
4 Alabama St. 26,500
5 Albany (NY) 8,500
6 Alcorn 22,500
7 Appalachian St. 30,000
8 Arizona 55,675
9 Arizona St. 64,248
10 Ark.-Pine Bluff 14,500
11 Arkansas 72,000
12 Arkansas St. 30,708
13 Army West Point 38,000
14 Auburn 87,451
15 Austin Peay 10,000
16 BYU 63,470
17 Ball St. 22,500
18 Baylor 45,140
19 Bethune-Cookman 9,601
20 Boise St. 36,387
21 Boston College 44,500
22 Bowling Green 24,000
23 Brown 20,000
24 Bucknell 13,100
25 Buffalo 29,013
26 Butler 5,647
27 Cal Poly 11,075
28 California 62,467
29 Central Conn. St. 5,500
.. ... ...
209 UCLA 91,136
210 UConn 40,000
211 UNI 16,324
212 UNLV 36,800
213 UT Martin 7,500
214 UTEP 52,000
215 Utah 45,807
216 Utah St. 25,100
217 VMI 10,000
218 Valparaiso 5,000
219 Vanderbilt 40,350
220 Villanova 12,000
221 Virginia 61,500
222 Virginia Tech 65,632
223 Wagner 3,300
224 Wake Forest 31,500
225 Washington 70,138
226 Washington St. 32,740
227 Weber St. 17,500
228 West Virginia 60,000
229 Western Caro. 13,742
230 Western Ill. 16,368
231 Western Ky. 22,113
232 Western Mich. 30,200
233 William & Mary 12,400
234 Wisconsin 80,321
235 Wofford 13,000
236 Wyoming 29,181
237 Yale 64,269
238 Youngstown St. 20,630
[239 rows x 2 columns]
注意: 这将需要很长时间。我们正在 抓取 >239 页。所以请耐心等待。可能需要 15 分钟或更长时间。