用Python中的BS4、嵌套表刮取数据
我正试图从Barball-reference.com上搜集一些数据。我已经编写了一些代码来从站点的其他部分获取数据,在这些部分中,表的编码稍微简单一些,但是特定的页面集显然更复杂。这是我到目前为止的代码 从urllib.request导入urlopen 从bs4导入BeautifulSoup用Python中的BS4、嵌套表刮取数据,python,web-scraping,beautifulsoup,Python,Web Scraping,Beautifulsoup,我正试图从Barball-reference.com上搜集一些数据。我已经编写了一些代码来从站点的其他部分获取数据,在这些部分中,表的编码稍微简单一些,但是特定的页面集显然更复杂。这是我到目前为止的代码 从urllib.request导入urlopen 从bs4导入BeautifulSoup # Declare URL test_url = 'https://www.baseball-reference.com/boxes/SLN/SLN201704020.shtml' # Query the
# Declare URL
test_url = 'https://www.baseball-reference.com/boxes/SLN/SLN201704020.shtml'
# Query the website and return the HTML
page = urlopen(test_url)
# Parse the HTML and store
soup = BeautifulSoup(page, 'lxml')
table = soup.find("div", {"class": "table_outer_container"})
但这找不到我想要的表(在这个特定页面上,有两个表,分别是At BAT、RBI、HRs、runs等)。我试过其他一些东西,例如
table = soup.find_all("table" , {"class": "sortable stats_table"})
但它也不起作用。我也尝试过使用pandas阅读网站,但运气不佳,因此如果有更简单的方法使用pandas,我也愿意接受。我知道这段代码很复杂或不好。但它完成了任务。随着时间的推移,您可以对其进行优化
from bs4 import BeautifulSoup,Comment
import requests
r = requests.get('https://www.baseball-reference.com/boxes/SLN/SLN201704020.shtml')
soup = BeautifulSoup(r.text, 'lxml')
comments = soup.find_all(string=lambda text:isinstance(text, Comment))
for comment in comments:
comment.extract()
#After getting rid of comments we need Soup again
another_soup = BeautifulSoup(str(comment),'lxml')
tables = another_soup.find_all('table' ,{"class": "sortable stats_table"})
for table in tables:
#Since we can't get id from table we are going to use table header as stat type.
stat_type = ''
for data in table.find('thead').find_all('tr'):
stat_type = data.th.text.strip()
#You only need batting.
if stat_type != 'Batting': break
for data in table.find('tbody').find_all('tr'):
player = data.th.text.strip()
stats = data.find_all('td')
stat_ab = stats[0].text
stat_r = stats[1].text
stat_h = stats[2].text
stat_rbi = stats[3].text
# Table goes on
print(player,stat_ab,stat_r,stat_h,stat_rbi)
print('-------------------------------------')
输出为:
Kyle Schwarber LF 3 0 2 0
Kris Bryant 3B 4 0 0 0
Anthony Rizzo 1B 4 0 1 0
Ben Zobrist RF 3 1 0 0
Addison Russell SS 4 0 1 0
Jason Heyward CF 4 1 1 0
Willson Contreras C 4 1 2 3
Jon Lester P 2 0 0 0
Carl Edwards P 0 0 0 0
Koji Uehara P 0 0 0 0
Tommy La Stella PH 1 0 0 0
Pedro Strop P 0 0 0 0
Jon Jay PH 1 0 0 0
Mike Montgomery P 0 0 0 0
Javier Baez 2B 4 0 1 0
-------------------------------------
Dexter Fowler CF 4 1 1 0
Aledmys Diaz SS 5 0 2 0
Matt Carpenter 1B 4 0 1 1
Jhonny Peralta 3B 4 0 1 0
Seung-hwan Oh P 0 0 0 0
Jose Martinez PH 1 1 1 0
Yadier Molina C 3 0 2 0
Stephen Piscotty RF 3 1 1 0
Jedd Gyorko 2B 2 0 0 0
Kolten Wong PH-2B 2 0 0 0
Randal Grichuk LF 4 1 2 3
Carlos Martinez P 3 0 0 0
Greg Garcia 3B 0 0 0 0
-------------------------------------
这是从两个表中获取数据的另一种方法:
import requests
from bs4 import BeautifulSoup, Comment
res = requests.get("https://www.baseball-reference.com/boxes/SLN/SLN201704020.shtml",headers={"User-Agent":"Mozilla/5.0"})
soup = BeautifulSoup(res.text, 'lxml')
for comment in soup.find_all(string=lambda text:isinstance(text,Comment)):
data = BeautifulSoup(comment,"lxml")
for items in data.select("#ChicagoCubsbatting tr,#StLouisCardinalsbatting tr"):
tds = ' '.join([' '.join(item.text.split()) for item in items.select("th,td")])
print(tds)
部分输出:
Batting AB R H RBI BB SO PA BA OBP SLG OPS Pit Str WPA aLI WPA+ WPA- RE24 PO A Details
Kyle Schwarber LF 3 0 2 0 0 1 4 .667 .750 1.000 1.750 20 10 0.170 1.75 0.196 -0.026 1.1 2 0 2B,HBP
Kris Bryant 3B 4 0 0 0 0 3 4 .000 .000 .000 .000 19 13 -0.260 2.31 0.000 -0.260 -1.6 0 0
Anthony Rizzo 1B 4 0 1 0 0 1 4 .250 .250 .250 .500 14 8 -0.214 2.74 0.035 -0.249 -0.9 5 0
看起来页面的整个部分都是用HTML作为注释编码的。我以前见过这个(大概是为了避开擦洗?),但不确定解决方法。相关-谢谢,只要我能在我的计算机上得到这个输出,这个方法就应该有效。我试图运行它,但我没有安装注释,当我尝试pip安装注释时,我得到一个错误。我试着到处找,但运气不好。提出一个新的问题。编辑:没关系,我不知道这个评论是BS4本身的一个包。那是浪费了几个小时。这很有效,谢谢。