如何提取整个表格并将其存储在CSV文件中?

时间:2019-12-20 04:05:49

标签: python csv web-scraping screen-scraping extraction

我正在尝试删除整个表,并希望将其存储在.csv文件中。 当我尝试抓取这些数据时,它显示为 没有桌子。

这是我的代码。

from pandas.io.html import read_html
page = 'https://games.crossfit.com/leaderboard/open/2020?view=0&division=1&scaled=0&sort=0'

tables = read_html(page,  attrs={"class":"desktop athletes"})

print ("Extracted {num} tables".format(num=len(tables)))

有任何建议或指导或帮助吗?

2 个答案:

答案 0 :(得分:2)

此页面使用JavaScript从服务器获取数据并生成表。

但是在Chrome / Firefox中使用DevTool,您可以看到(在标签Network中)从浏览器到服务器的所有请求,其中XHR/AJAX个请求之一获取了{{1} }格式,因此您也可以使用此网址以JSON的形式获取它,您可以将其转换为Python数据,而不必进行抓取。

JSON

结果

import requests

r = requests.get('https://games.crossfit.com/competitions/api/v1/competitions/open/2020/leaderboards?view=0&division=1&scaled=0&sort=0')

data = r.json()

for row in data['leaderboardRows']:
    print(row['entrant']['competitorName'], row['overallScore'], [(x['rank'],x['scoreDisplay']) for x in row['scores']])

答案 1 :(得分:0)

如下所述,您可以访问api以获取数据。要保存为CSV,您需要遍历json格式以获取所需的内容(即,将嵌套数据展平)。有两种方法可以完成此操作:a)将其完全展平,以使每个行对应每个参赛者,或b)每个参赛者针对其每个序数得分都有单独的行。

唯一的区别是,如果选择a)您将拥有一张非常宽的表(但没有重复的数据),并且如果选择b)您将拥有一张长表且具有重复的数据。

>

由于文件不是太大,我使用了选项b),因此您始终可以按特定的列或过滤器进行分组:

undefined

输出:前15行,共250行

import requests
import pandas as pd

r = requests.get('https://games.crossfit.com/competitions/api/v1/competitions/open/2020/leaderboards?view=0&division=1&scaled=0&sort=0')

data = r.json()

results = pd.DataFrame()
df = pd.DataFrame(data['leaderboardRows'])

for idx, row in df.iterrows():
    entrantData = pd.Series()
    scoresData = pd.DataFrame()
    entrantResults = pd.DataFrame()
    for idx2, each in row.iteritems():
        if type(each) == dict:
            temp = pd.DataFrame.from_dict(each, orient='index')
            entrantData = entrantData.append(temp)
        elif type(each) == list:
            temp2 = pd.DataFrame(each)
            scoresData = scoresData.append(temp2, sort=True).reset_index(drop=True)
        else:
            entrantData = entrantData.append(pd.Series(each, name=idx2))

    entrantResults = entrantResults.append(scoresData, sort=True).reset_index(drop=True)
    entrantResults = entrantResults.merge(pd.concat([entrantData.T] *5, ignore_index=True), left_index=True, right_index=True)

    results = results.append(entrantResults, sort=True).reset_index(drop=True)

results.to_csv('file.csv', index=False)