首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >BeautifulSoup和CSV文件

BeautifulSoup和CSV文件
EN

Stack Overflow用户
提问于 2015-04-27 21:33:51
回答 2查看 321关注 0票数 0

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

我做过这件事,但有几个问题。表的第一列既包含了播放器的排名,也包含了它们的名称。我想把它们分开,这样一个列只包含排名,另一个列包含播放器名。

下面是代码:

代码语言:javascript
运行
复制
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)

以下是几位玩家的作品:

代码语言:javascript
运行
复制
"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代码比其他列略复杂:

代码语言:javascript
运行
复制
<td class="col1" rel="1">1
                            <a href="/Tennis/Players/Top-Players/Novak-Djokovic.aspx">Novak Djokovic</a></td>

我试着把它和它分开,但是我无法让它工作,并且认为修复当前的CSV文件可能更容易。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-27 21:38:33

把它拉出来后把它分开是很容易的。你有一个数字,一堆空格,还有一个名字。因此,只需使用split,并使用默认分隔符,最大分隔数为1:

代码语言:javascript
运行
复制
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)

但是,您也可以将其与汤中的内容分离开来,这可能会更加健壮:

代码语言:javascript
运行
复制
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]
票数 2
EN

Stack Overflow用户

发布于 2015-04-27 21:53:41

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

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

代码语言:javascript
运行
复制
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()
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29906355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档