BeautifulSoup和CSV文件

时间:2015-04-27 21:33:51

标签: python python-2.7 csv beautifulsoup

我希望从http://www.atpworldtour.com/Rankings/Top-Matchfacts.aspx?y=2015&s=1#拉出表格,并将所有信息都放在csv文件中。

我已经完成了这项工作,但我遇到了一些问题。表格的第一列包含玩家的排名和他们的名字。我想将它们分开,以便一列只包含排名而另一列包含播放器名称。

以下是代码:

import urllib2
from bs4 import BeautifulSoup
import csv

URL = 'http://www.atpworldtour.com/Rankings/Top-Matchfacts.aspx?y=2015&s=1#'
req = urllib2.Request(URL)
page = urllib2.urlopen(req)
soup = BeautifulSoup(page)
tables = soup.findAll('table')
my_table = tables[0]

with open('out2.csv', 'w') as f:
    csvwriter = csv.writer(f)
    for row in my_table.findAll('tr'):
        cells = [c.text.encode('utf-8') for c in row.findAll('td')]
        if len(cells) == 16: 
            csvwriter.writerow(cells)

以下是一些玩家的输出:

"1
                            Novak Djokovic",SRB,5-0,0-0,9,1.8,7,1.4,62%,74%,58%,88%,42%,68%,39%-57%,46%
"2
                            Roger Federer",SUI,1-1,0-1,9,4.5,2,1.0,59%,68%,54%,84%,46%,67%,37%-49%,33%
"3
                            Andy Murray",GBR,0-0,0-0,0,0.0,0,0.0,0%,0%,0%,0%,0%,0%,0%-0%,0%
"4
                            Rafael Nadal",ESP,11-3,2-1,25,1.8,18,1.3,68%,69%,57%,82%,43%,57%,36%-58%,38%
"5
                            Kei Nishikori",JPN,5-0,0-0,14,2.8,9,1.8,57%,75%,62%,92%,49%,80%,39%-62%,42%

正如您所看到的那样,第一列没有正确显示,数字位于比其他数据更高的行以及极大的间隙。

问题列的HTML代码比其他列稍微复杂一些:

<td class="col1" rel="1">1
                            <a href="/Tennis/Players/Top-Players/Novak-Djokovic.aspx">Novak Djokovic</a></td>

我尝试将其与之分开,但我无法让它工作,并认为修复当前的CSV文件可能更容易。

2 个答案:

答案 0 :(得分:2)

拔出后将场分开非常容易。你有一个数字,一堆空格和一个名字。因此,只需使用split,使用默认分隔符,最大分割为1:

cells = [c.text.encode('utf-8') for c in row.findAll('td')]
if len(cells) == 16:
    cells[0:1] = cells[0].split(None, 1)
    csvwriter.writerow(cells)

但你也可以将它与汤中分开,这可能更强大:

cells = row.find_all('td')
cell0 = cells.pop(0)
rank = next(cell0.children).strip().encode('utf-8')
name = cell0.find('a').text.encode('utf-8')
cells = [rank, name] + [c.text.encode('utf-8') for c in cells]

答案 1 :(得分:-1)

由于您关注的值包含多个标签,并且播放器的名称直接位于最终标签之后,我建议按标签拆分并从结果元组中收集最后一项。

我添加的行是cells[0] = cells[0].split('\t')[-1]

import urllib2
from bs4 import BeautifulSoup
import csv

URL = 'http://www.atpworldtour.com/Rankings/Top-Matchfacts.aspx?y=2015&s=1#'
req = urllib2.Request(URL)
page = urllib2.urlopen(req)
soup = BeautifulSoup(page)
tables = soup.findAll('table')
my_table = tables[0]

with open('out2.csv', 'w') as f:
    csvwriter = csv.writer(f)
    for row in my_table.findAll('tr'):
        cells = [c.text.encode('utf-8') for c in row.findAll('td')]
        if len(cells) == 16: 
            cells[0] = cells[0].split('\t')[-1]
            csvwriter.writerow(cells)

f.close()