当'data-append-csv'中每行的数据从网站检索一个表

时间:2016-10-30 20:18:55

标签: python web-scraping beautifulsoup

我正在尝试使用网站上的beautifulsoup废弃数据,如下所示:

http://www.basketball-reference.com/players/a/

其中包含所有篮球运动员数据的表格。当我检查html源元素时。似乎在每个表行('tr')中,播放器数据包含在'data-append-csv'中。这是播放器表格中的一个tr的快照。

<tr data-row="0"><th scope="row" class="left " data-append-csv="abdelal01" data-stat="player"></th></tr>

我应该如何从每个表格行中提取数据?

def make_soup(url):
thePage = urllib.request.urlopen(url)
soup = BeautifulSoup(thePage, 'html.parser')
return(soup)
r='http://www.basketball-reference.com/players/a/'
soup = make_soup(r)
for record in soup.find_all('tr')[1:]:
    print(record.text)

这是第一张显示的记录:

Alaa Abdelnaby19911995F-C6-10240June 24, 1968Duke University

所有数据都在一个字符串中,没有分离。 我该如何提取所有数据表?非常感谢你的帮助!

1 个答案:

答案 0 :(得分:-1)

我不确定我是否理解你要做的事情,这里是一个从你提供的页面中提取玩家所有数据的例子。它不是最美丽的(汤:)),但应该让你知道如何处理事情。而且,这不是唯一的方法,只是我想到的那个。

import requests
from bs4 import BeautifulSoup

page = requests.get("http://www.basketball-reference.com/players/a/")
soup = BeautifulSoup(page.content,'html.parser')

for record in soup.find_all('tr'):
    try: #Crude way of handling NavigableString Error that pop ups with these multi tag lines
        print record.contents[0].text
        print record.contents[1].text
        print record.contents[2].text
        print record.contents[3].text
        print record.contents[4].text
        print record.contents[5].text
        print record.contents[6].text
        print record.contents[7].text
    except:
        pass
    print '\n'

修改

以下是代码的工作原理。

首先,'for'正在寻找<tr></tr>的所有事件。 。返回的每一行都将以<tr>标记打开,并以</tr>标记结束 - 示例如下

for record in soup.find_all('tr'):
     print record

<tr><th class="left " data-append-csv="abdelal01" data-stat="player" scope="row"><a href="/players/a/abdelal01.html">Alaa Abdelnaby</a></th><td class="right " data-stat="year_min">1991</td><td class="right " data-stat="year_max">1995</td><td class="center " data-stat="pos">F-C</td><td class="right " csk="82.0" data-stat="height">6-10</td><td class="right " data-stat="weight">240</td><td class="left " csk="19680624" data-stat="birth_date"><a href="/friv/birthdays.cgi?month=6&amp;day=24">June 24, 1968</a></td><td class="left " data-stat="college_name"><a href="/friv/colleges.cgi?college=duke">Duke University</a></td></tr>

所以我们最终得到一条完整的<tr></tr>行。现在我们使用.contents将返回的字符串转换为列表

for record in soup.find_all('tr'):
     print record.content

[<th class="left " data-append-csv="abdelal01" data-stat="player" scope="row"><a href="/players/a/abdelal01.html">Alaa Abdelnaby</a></th>, <td class="right " data-stat="year_min">1991</td>, <td class="right " data-stat="year_max">1995</td>, <td class="center " data-stat="pos">F-C</td>, <td class="right " csk="82.0" data-stat="height">6-10</td>, <td class="right " data-stat="weight">240</td>, <td class="left " csk="19680624" data-stat="birth_date"><a href="/friv/birthdays.cgi?month=6&amp;day=24">June 24, 1968</a></td>, <td class="left " data-stat="college_name"><a href="/friv/colleges.cgi?college=duke">Duke University</a></td>]

因为我们正在处理一个不是长字符串的列表,所以它很简单。使用[n]我们可以从列表中访问第n个项目。让我们打印出第一个项目

for record in soup.find_all('tr'):
    print record.content[0]

<th class="left " data-append-csv="abdelal01" data-stat="player" scope="row"><a href="/players/a/abdelal01.html">Alaa Abdelnaby</a></th>

如你所见,我们有两个标签。 <th><a>以及标记之间的文本,而不是标记本身。这就是.text所做的 - 它省略了所有标签并仅抓取网站上显示的实际文本。

for record in soup.find_all('tr'):
    print record.content[0].text

Alaa Abdelnaby

希望有所帮助:)