{ "cells": [ { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "url_base='http://www.wrc.com/service/sasCacheApi.php?route={stub}'" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "itinerary_stub='rallies/{rallyId}/itinerary'\n", "startlists_stub='rallies/{rallyId}/entries'\n", "penalties_stub='rallies/{rallyId}/penalties'\n", "retirements_stub='rallies/{rallyId}/retirements'\n", "stagewinners_stub='rallies/{rallyId}/stagewinners'\n", "\n", "\n", "overall_stub='stages/{stageId}/results?rallyId={rallyId}'\n", "split_times_stub ='stages/{stageId}/splittimes?rallyId={rallyId}'\n", "stage_times_stage_stub='stages/{stageId}/stagetimes?rallyId={rallyId}'\n", "stage_times_overall_stub='stages/{stageId}/results?rallyId={rallyId}'\n", "\n", "championship_stub='championships/{championshipId}'\n", "championship_results_stub='championships/{championshipId}/results'" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "meta={'rallyId':30}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Scrape page for rallyid\n", "\n", "The `rallyid` used in the API seems to differ from IDs in the data returned by the API, so we need to scrape the rally pages to get the actual ID." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "import requests\n", "import re\n", "from bs4 import BeautifulSoup " ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "results_main_url='http://www.wrc.com/en/wrc/results/wales/stage-times/page/416-238---.html#'" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "html=requests.get(results_main_url)\n", "soup=BeautifulSoup(html.content, \"html5lib\")\n", "#BeautifulSoup has a routine - find_all() - that will find all the HTML tags of a particular sort\n", "#Links are represented in HTML pages in the form link text\n", "#Grab all the (anchor) tags...\n", "souplist=soup.findAll(\"li\",{'class':'flag'})" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Argentina': 'http://www.wrc.com/en/wrc/results/argentina/stage-times/page/346-230---.html',\n", " 'Australia': 'http://www.wrc.com/en/wrc/results/australia/stage-times/page/392-235---.html',\n", " 'Finland': 'http://www.wrc.com/en/wrc/results/finland/stage-times/page/376-233---.html',\n", " 'France': 'http://www.wrc.com/en/wrc/results/france/stage-times/page/400-236---.html',\n", " 'Germany': 'http://www.wrc.com/en/wrc/results/germany/stage-times/page/384-234---.html',\n", " 'Italy': 'http://www.wrc.com/en/wrc/results/italy/stage-times/page/360-231---.html',\n", " 'Mexico': 'http://www.wrc.com/en/wrc/results/mexico/stage-times/page/334-228---.html',\n", " 'Monaco': 'http://www.wrc.com/en/wrc/results/monte-carlo/stage-times/page/318-226---.html',\n", " 'Portugal': 'http://www.wrc.com/en/wrc/results/portugal/stage-times/page/342-229---.html',\n", " 'Spain': 'http://www.wrc.com/en/wrc/results/spain/stage-times/page/408-237---.html',\n", " 'Sweden': 'http://www.wrc.com/en/wrc/results/sweden/stage-times/page/326-227---.html',\n", " 'Turkey': 'http://www.wrc.com/en/wrc/results/turkey/stage-times/page/368-232---.html',\n", " 'Wales': 'http://www.wrc.com/en/wrc/results/wales/stage-times/page/416-238---.html'}" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "items={}\n", "for s in souplist:\n", " href=s.find('a')['href']\n", " if href:\n", " title=s.find('img')['title']\n", " title = 'Monaco' if title == 'Monte Carlo' else title\n", " items[title]=href\n", "items" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the names don't properly match any single column in other tables. Need to match on either country or location in championship table - or change \"Monte Carlo\" to \"Monaco\"." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "url='http://www.wrc.com/en/wrc/results/wales/stage-times/page/416-238---.html'\n", "html=requests.get(url)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "m = re.search(\"var rallyId = '(.+?)'\", html.text)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "40\n" ] } ], "source": [ "if m:\n", " print(m.group(1))" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import requests" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Argentina': '34',\n", " 'Australia': '42',\n", " 'Finland': '37',\n", " 'France': '33',\n", " 'Germany': '38',\n", " 'Italy': '36',\n", " 'Mexico': '32',\n", " 'Monaco': '30',\n", " 'Portugal': '35',\n", " 'Spain': '41',\n", " 'Sweden': '31',\n", " 'Turkey': '39',\n", " 'Wales': '40'}" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rallyids={}\n", "for item in items:\n", " html=requests.get(items[item])\n", " m = re.search(\"var rallyId = '(.+?)'\", html.text)\n", " if m:\n", " rallyids[item] = m.group(1)\n", "rallyids " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Itinerary" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "itinerary_json=requests.get( url_base.format(stub=itinerary_stub.format(**meta) ) ).json()\n", "#itinerary_json" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If no data is returned, we get an empty list.\n", "\n", "Need to check that we do get a response, eg `if itinerary_json:`" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'eventId': 26,\n", " 'itineraryId': 31,\n", " 'itineraryLegs': [{'itineraryId': 31,\n", " 'itineraryLegId': 46,\n", " 'itinerarySections': [{'controls': [{'code': 'TC0',\n", " 'controlId': 1066,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-25T16:50:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-25T17:50:00+01:00',\n", " 'location': 'Monaco - Depart Day 1',\n", " 'stageId': None,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC1',\n", " 'controlId': 1133,\n", " 'distance': 192.71,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-25T20:40:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-25T21:40:00+01:00',\n", " 'location': 'Thoard',\n", " 'stageId': 289,\n", " 'status': 'Completed',\n", " 'targetDuration': '03:50:00',\n", " 'targetDurationMs': 13800000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS1',\n", " 'controlId': 1134,\n", " 'distance': 36.69,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-25T20:43:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-25T21:43:00+01:00',\n", " 'location': 'Thoard - Sisteron',\n", " 'stageId': 289,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF1',\n", " 'controlId': 1135,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'Thoard - Sisteron',\n", " 'stageId': 289,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC2',\n", " 'controlId': 1123,\n", " 'distance': 30.71,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-25T21:48:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-25T22:48:00+01:00',\n", " 'location': 'Bayons',\n", " 'stageId': 287,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:05:00',\n", " 'targetDurationMs': 3900000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS2',\n", " 'controlId': 1131,\n", " 'distance': 25.49,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-25T21:51:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-25T22:51:00+01:00',\n", " 'location': 'Bayons- Breziers 1',\n", " 'stageId': 287,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF2',\n", " 'controlId': 1122,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'Bayons- Breziers 1',\n", " 'stageId': 287,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC2A',\n", " 'controlId': 1128,\n", " 'distance': 25.65,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-25T22:46:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-25T23:46:00+01:00',\n", " 'location': 'Technical Zone (IN)',\n", " 'stageId': 287,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:55:00',\n", " 'targetDurationMs': 3300000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC2B',\n", " 'controlId': 1145,\n", " 'distance': 0.1,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-25T22:56:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-25T23:56:00+01:00',\n", " 'location': 'Technical Zone (OUT) - Flexi Service (IN)',\n", " 'stageId': 287,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:10:00',\n", " 'targetDurationMs': 600000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC2C',\n", " 'controlId': 1142,\n", " 'distance': 1.3,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-25T23:44:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T00:44:00+01:00',\n", " 'location': 'Flexi Service (OUT) - Parc Ferme (IN)',\n", " 'stageId': 287,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:48:00',\n", " 'targetDurationMs': 2880000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'}],\n", " 'itineraryLegId': 46,\n", " 'itinerarySectionId': 106,\n", " 'name': 'Section 1',\n", " 'order': 1,\n", " 'stages': [{'code': 'SS1',\n", " 'distance': 36.69,\n", " 'eventId': 26,\n", " 'name': 'Thoard - Sisteron',\n", " 'number': 1,\n", " 'stageId': 289,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'},\n", " {'code': 'SS2',\n", " 'distance': 25.49,\n", " 'eventId': 26,\n", " 'name': 'Bayons - Breziers 1',\n", " 'number': 2,\n", " 'stageId': 287,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'}]}],\n", " 'legDate': '2018-01-25',\n", " 'name': 'Thursday 25th January 2018',\n", " 'order': 1,\n", " 'startListId': 66,\n", " 'status': 'Running'},\n", " {'itineraryId': 31,\n", " 'itineraryLegId': 47,\n", " 'itinerarySections': [{'controls': [{'code': 'TC2D',\n", " 'controlId': 1143,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T07:00:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T08:00:00+01:00',\n", " 'location': 'Parc Ferme (OUT) - Service (IN)',\n", " 'stageId': 287,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC2E',\n", " 'controlId': 1144,\n", " 'distance': 1.3,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T07:18:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T08:18:00+01:00',\n", " 'location': 'Service (OUT)',\n", " 'stageId': 287,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:18:00',\n", " 'targetDurationMs': 1080000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC3',\n", " 'controlId': 1140,\n", " 'distance': 22.61,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T07:48:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T08:48:00+01:00',\n", " 'location': 'Vitrolles',\n", " 'stageId': 286,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:30:00',\n", " 'targetDurationMs': 1800000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS3',\n", " 'controlId': 1141,\n", " 'distance': 26.72,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T07:51:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T08:51:00+01:00',\n", " 'location': 'Vitrolles - Oze 1',\n", " 'stageId': 286,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF3',\n", " 'controlId': 1125,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'Vitrolles - Oze 1',\n", " 'stageId': 286,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC4',\n", " 'controlId': 1132,\n", " 'distance': 47.33,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T09:01:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T10:01:00+01:00',\n", " 'location': 'Roussieux',\n", " 'stageId': 285,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:10:00',\n", " 'targetDurationMs': 4200000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS4',\n", " 'controlId': 1120,\n", " 'distance': 30.54,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T09:04:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T10:04:00+01:00',\n", " 'location': 'Roussieux - Eygalayes 1',\n", " 'stageId': 285,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF4',\n", " 'controlId': 1121,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'Roussieux - Eygalayes 1',\n", " 'stageId': 285,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC5',\n", " 'controlId': 1126,\n", " 'distance': 48.56,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T10:34:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T11:34:00+01:00',\n", " 'location': 'Vaumeilh',\n", " 'stageId': 284,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:30:00',\n", " 'targetDurationMs': 5400000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS5',\n", " 'controlId': 1119,\n", " 'distance': 15.18,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T10:37:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T11:37:00+01:00',\n", " 'location': 'Vaumeilh - Claret 1',\n", " 'stageId': 284,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF5',\n", " 'controlId': 1124,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'Vaumeilh - Claret 1',\n", " 'stageId': 284,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC5A',\n", " 'controlId': 1127,\n", " 'distance': 30.31,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T11:32:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T12:32:00+01:00',\n", " 'location': 'Technical Zone and Regroup (IN)',\n", " 'stageId': 284,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:55:00',\n", " 'targetDurationMs': 3300000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'}],\n", " 'itineraryLegId': 47,\n", " 'itinerarySectionId': 107,\n", " 'name': 'Section 2',\n", " 'order': 2,\n", " 'stages': [{'code': 'SS3',\n", " 'distance': 26.72,\n", " 'eventId': 26,\n", " 'name': 'Vitrolles - Oze 1',\n", " 'number': 3,\n", " 'stageId': 286,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'},\n", " {'code': 'SS4',\n", " 'distance': 30.54,\n", " 'eventId': 26,\n", " 'name': 'Roussieux - Eygalayes 1',\n", " 'number': 4,\n", " 'stageId': 285,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'},\n", " {'code': 'SS5',\n", " 'distance': 15.18,\n", " 'eventId': 26,\n", " 'name': 'Vaumeilh - Claret 1',\n", " 'number': 5,\n", " 'stageId': 284,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'}]},\n", " {'controls': [{'code': 'TC5B',\n", " 'controlId': 1129,\n", " 'distance': 0.1,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T11:52:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T12:52:00+01:00',\n", " 'location': 'Technical Zone and Regroup (OUT) - Service (IN)',\n", " 'stageId': 284,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:20:00',\n", " 'targetDurationMs': 1200000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC5C',\n", " 'controlId': 1130,\n", " 'distance': 1.3,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T12:25:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T13:25:00+01:00',\n", " 'location': 'Service (OUT)',\n", " 'stageId': 284,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:33:00',\n", " 'targetDurationMs': 1980000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC6',\n", " 'controlId': 1139,\n", " 'distance': 22.61,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T12:55:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T13:55:00+01:00',\n", " 'location': 'Vitrolles',\n", " 'stageId': 283,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:30:00',\n", " 'targetDurationMs': 1800000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS6',\n", " 'controlId': 1138,\n", " 'distance': 26.72,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T12:58:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T13:58:00+01:00',\n", " 'location': 'Vitrolles - Oze 2',\n", " 'stageId': 283,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF6',\n", " 'controlId': 1137,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'Vitrolles - Oze 2',\n", " 'stageId': 283,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC7',\n", " 'controlId': 1091,\n", " 'distance': 47.33,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T14:08:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T15:08:00+01:00',\n", " 'location': 'Roussieux',\n", " 'stageId': 282,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:10:00',\n", " 'targetDurationMs': 4200000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS7',\n", " 'controlId': 1117,\n", " 'distance': 30.54,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T14:11:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T15:11:00+01:00',\n", " 'location': 'Roussieux - Eygalayes 2',\n", " 'stageId': 282,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF7',\n", " 'controlId': 1136,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'Roussieux - Eygalayes 2',\n", " 'stageId': 282,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC8',\n", " 'controlId': 1087,\n", " 'distance': 48.56,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T15:41:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T16:41:00+01:00',\n", " 'location': 'Vaumeilh',\n", " 'stageId': 281,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:30:00',\n", " 'targetDurationMs': 5400000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS8',\n", " 'controlId': 1088,\n", " 'distance': 15.18,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T15:44:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T16:44:00+01:00',\n", " 'location': 'Vaumeilh - Claret 2',\n", " 'stageId': 281,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF8',\n", " 'controlId': 1089,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'Vaumeilh - Claret 2',\n", " 'stageId': 281,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC8A',\n", " 'controlId': 1086,\n", " 'distance': 30.31,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T16:39:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T17:39:00+01:00',\n", " 'location': 'Technical Zone (IN)',\n", " 'stageId': 281,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:55:00',\n", " 'targetDurationMs': 3300000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC8B',\n", " 'controlId': 1085,\n", " 'distance': 0.1,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T16:49:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T17:49:00+01:00',\n", " 'location': 'Technical Zone (OUT) - Flexi Service (IN)',\n", " 'stageId': 281,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:10:00',\n", " 'targetDurationMs': 600000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC8C',\n", " 'controlId': 1084,\n", " 'distance': 1.3,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-26T17:37:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-26T18:37:00+01:00',\n", " 'location': 'Flexi Service (OUT) - Parc Ferme (IN)',\n", " 'stageId': 281,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:48:00',\n", " 'targetDurationMs': 2880000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'}],\n", " 'itineraryLegId': 47,\n", " 'itinerarySectionId': 108,\n", " 'name': 'Section 3',\n", " 'order': 3,\n", " 'stages': [{'code': 'SS6',\n", " 'distance': 26.72,\n", " 'eventId': 26,\n", " 'name': 'Vitrolles - Oze 2',\n", " 'number': 6,\n", " 'stageId': 283,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'},\n", " {'code': 'SS7',\n", " 'distance': 30.54,\n", " 'eventId': 26,\n", " 'name': 'Roussieux - Eygalayes 2',\n", " 'number': 7,\n", " 'stageId': 282,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'},\n", " {'code': 'SS8',\n", " 'distance': 15.18,\n", " 'eventId': 26,\n", " 'name': 'Vaumeilh - Claret 2',\n", " 'number': 8,\n", " 'stageId': 281,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'}]}],\n", " 'legDate': '2018-01-26',\n", " 'name': 'Friday 26th January 2018',\n", " 'order': 2,\n", " 'startListId': 68,\n", " 'status': 'Running'},\n", " {'itineraryId': 31,\n", " 'itineraryLegId': 48,\n", " 'itinerarySections': [{'controls': [{'code': 'TC8D',\n", " 'controlId': 1083,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T05:57:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T06:57:00+01:00',\n", " 'location': 'Parc Ferme (OUT) - Service (IN)',\n", " 'stageId': 281,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC8E',\n", " 'controlId': 1067,\n", " 'distance': 1.3,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T06:15:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T07:15:00+01:00',\n", " 'location': 'Service (OUT)',\n", " 'stageId': 281,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:18:00',\n", " 'targetDurationMs': 1080000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC9',\n", " 'controlId': 1090,\n", " 'distance': 40.68,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T07:05:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T08:05:00+01:00',\n", " 'location': 'Agnieres En Devoluy',\n", " 'stageId': 280,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:50:00',\n", " 'targetDurationMs': 3000000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS9',\n", " 'controlId': 1080,\n", " 'distance': 29.16,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T07:08:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T08:08:00+01:00',\n", " 'location': 'Agnieres En Devoluy - Corps 1',\n", " 'stageId': 280,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF9',\n", " 'controlId': 1081,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'Agnieres En Devoluy - Corps 1',\n", " 'stageId': 280,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC10',\n", " 'controlId': 1076,\n", " 'distance': 37.96,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T08:13:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T09:13:00+01:00',\n", " 'location': 'St Leger Les Melezes',\n", " 'stageId': 279,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:05:00',\n", " 'targetDurationMs': 3900000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS10',\n", " 'controlId': 1077,\n", " 'distance': 16.87,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T08:16:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T09:16:00+01:00',\n", " 'location': 'St Leger Les Melezes - La Batie Neuve 1',\n", " 'stageId': 279,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF10',\n", " 'controlId': 1079,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'St Leger Les Melezes - La Batie Neuve 1',\n", " 'stageId': 279,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC10A',\n", " 'controlId': 1075,\n", " 'distance': 29.58,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T09:16:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T10:16:00+01:00',\n", " 'location': 'Technical Zone and Regroup (IN)',\n", " 'stageId': 279,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:00:00',\n", " 'targetDurationMs': 3600000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'}],\n", " 'itineraryLegId': 48,\n", " 'itinerarySectionId': 109,\n", " 'name': 'Section 4',\n", " 'order': 4,\n", " 'stages': [{'code': 'SS9',\n", " 'distance': 29.16,\n", " 'eventId': 26,\n", " 'name': 'Agnieres En Devoluy - Corps 1',\n", " 'number': 9,\n", " 'stageId': 280,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'},\n", " {'code': 'SS10',\n", " 'distance': 16.87,\n", " 'eventId': 26,\n", " 'name': 'St Leger Les Melezes - La Batie Neuve 1',\n", " 'number': 10,\n", " 'stageId': 279,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'}]},\n", " {'controls': [{'code': 'TC10B',\n", " 'controlId': 1074,\n", " 'distance': 0.1,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T09:31:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T10:31:00+01:00',\n", " 'location': 'Technical Zone and Regroup (OUT) - Service (IN)',\n", " 'stageId': 279,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:15:00',\n", " 'targetDurationMs': 900000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC10C',\n", " 'controlId': 1073,\n", " 'distance': 1.3,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T10:04:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T11:04:00+01:00',\n", " 'location': 'Service (OUT)',\n", " 'stageId': 279,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:33:00',\n", " 'targetDurationMs': 1980000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC11',\n", " 'controlId': 1070,\n", " 'distance': 40.68,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T10:54:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T11:54:00+01:00',\n", " 'location': 'Agnieres En Devoluy - Corps 2',\n", " 'stageId': 278,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:50:00',\n", " 'targetDurationMs': 3000000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS11',\n", " 'controlId': 1071,\n", " 'distance': 29.16,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T10:57:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T11:57:00+01:00',\n", " 'location': 'Agnieres En Devoluy - Corps 2',\n", " 'stageId': 278,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF11',\n", " 'controlId': 1072,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'Agnieres En Devoluy - Corps 2',\n", " 'stageId': 278,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC12',\n", " 'controlId': 1078,\n", " 'distance': 37.96,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T12:02:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T13:02:00+01:00',\n", " 'location': 'St Leger Les Melezes - La Batie Neuve 2',\n", " 'stageId': 277,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:05:00',\n", " 'targetDurationMs': 3900000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS12',\n", " 'controlId': 1068,\n", " 'distance': 16.87,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T12:08:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T13:08:00+01:00',\n", " 'location': 'St Leger Les Melezes - La Batie Neuve 2',\n", " 'stageId': 277,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:06:00',\n", " 'targetDurationMs': 360000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF12',\n", " 'controlId': 1069,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'St Leger Les Melezes - La Batie Neuve 2',\n", " 'stageId': 277,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC12A',\n", " 'controlId': 1092,\n", " 'distance': 29.58,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T13:08:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T14:08:00+01:00',\n", " 'location': 'Technical Zone and Regroup (IN)',\n", " 'stageId': 277,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:00:00',\n", " 'targetDurationMs': 3600000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'}],\n", " 'itineraryLegId': 48,\n", " 'itinerarySectionId': 110,\n", " 'name': 'Section 5',\n", " 'order': 5,\n", " 'stages': [{'code': 'SS11',\n", " 'distance': 29.16,\n", " 'eventId': 26,\n", " 'name': 'Agnieres En Devoluy - Corps 2',\n", " 'number': 11,\n", " 'stageId': 278,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'},\n", " {'code': 'SS12',\n", " 'distance': 16.87,\n", " 'eventId': 26,\n", " 'name': 'St Leger Les Melezes - La Batie Neuve 2',\n", " 'number': 12,\n", " 'stageId': 277,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'}]},\n", " {'controls': [{'code': 'TC12B',\n", " 'controlId': 1104,\n", " 'distance': 0.1,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T13:23:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T14:23:00+01:00',\n", " 'location': 'Technical Zone and Regroup (OUT) - Service (IN)',\n", " 'stageId': 277,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:15:00',\n", " 'targetDurationMs': 900000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC12C',\n", " 'controlId': 1093,\n", " 'distance': 1.3,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T13:56:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T14:56:00+01:00',\n", " 'location': 'Service (OUT)',\n", " 'stageId': 277,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:33:00',\n", " 'targetDurationMs': 1980000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC13',\n", " 'controlId': 1113,\n", " 'distance': 53.13,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T15:06:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T16:06:00+01:00',\n", " 'location': 'Bayons',\n", " 'stageId': 276,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:10:00',\n", " 'targetDurationMs': 4200000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS13',\n", " 'controlId': 1114,\n", " 'distance': 25.49,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T15:09:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T16:09:00+01:00',\n", " 'location': 'Bayons- Breziers 2',\n", " 'stageId': 276,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF13',\n", " 'controlId': 1115,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'Bayons- Breziers 2',\n", " 'stageId': 276,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC13A',\n", " 'controlId': 1112,\n", " 'distance': 25.65,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T16:19:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T17:19:00+01:00',\n", " 'location': 'Technical Zone (IN)',\n", " 'stageId': 276,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:10:00',\n", " 'targetDurationMs': 4200000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC13B',\n", " 'controlId': 1111,\n", " 'distance': 0.1,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T16:29:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T17:29:00+01:00',\n", " 'location': 'Technical Zone (OUT) - Service (IN)',\n", " 'stageId': 276,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:10:00',\n", " 'targetDurationMs': 600000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC13C',\n", " 'controlId': 1110,\n", " 'distance': 1.3,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T17:17:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T18:17:00+01:00',\n", " 'location': 'Service (OUT)',\n", " 'stageId': 276,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:48:00',\n", " 'targetDurationMs': 2880000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC13D',\n", " 'controlId': 1109,\n", " 'distance': 240.3,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-27T20:17:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-27T21:17:00+01:00',\n", " 'location': 'Parc Ferme Monaco (IN)',\n", " 'stageId': 276,\n", " 'status': 'Completed',\n", " 'targetDuration': '04:00:00',\n", " 'targetDurationMs': 14400000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'}],\n", " 'itineraryLegId': 48,\n", " 'itinerarySectionId': 111,\n", " 'name': 'Section 6',\n", " 'order': 6,\n", " 'stages': [{'code': 'SS13',\n", " 'distance': 25.49,\n", " 'eventId': 26,\n", " 'name': 'Bayons - Breziers 2',\n", " 'number': 13,\n", " 'stageId': 276,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'}]}],\n", " 'legDate': '2018-01-27',\n", " 'name': 'Saturday 27th January 2018',\n", " 'order': 3,\n", " 'startListId': 70,\n", " 'status': 'Running'},\n", " {'itineraryId': 31,\n", " 'itineraryLegId': 49,\n", " 'itinerarySections': [{'controls': [{'code': 'TC13E',\n", " 'controlId': 1108,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T05:49:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T06:49:00+01:00',\n", " 'location': 'Monaco - Parc Ferme (OUT)',\n", " 'stageId': 276,\n", " 'status': 'Completed',\n", " 'targetDuration': '08:32:00',\n", " 'targetDurationMs': 30720000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC14',\n", " 'controlId': 1116,\n", " 'distance': 69.86,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T07:29:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T08:29:00+01:00',\n", " 'location': 'La Bollene Vesubie',\n", " 'stageId': 275,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:40:00',\n", " 'targetDurationMs': 6000000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS14',\n", " 'controlId': 1106,\n", " 'distance': 18.41,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T07:32:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T08:32:00+01:00',\n", " 'location': 'La Bollene Vesubie - Peira Cava 1',\n", " 'stageId': 275,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF14',\n", " 'controlId': 1107,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'La Bollene Vesubie - Peira Cava 1',\n", " 'stageId': 275,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC15',\n", " 'controlId': 1102,\n", " 'distance': 3.43,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T08:02:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T09:02:00+01:00',\n", " 'location': 'La Cabanette',\n", " 'stageId': 274,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:30:00',\n", " 'targetDurationMs': 1800000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS15',\n", " 'controlId': 1103,\n", " 'distance': 13.58,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T08:08:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T09:08:00+01:00',\n", " 'location': 'La Cabanette - Col De Braus 1',\n", " 'stageId': 274,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:06:00',\n", " 'targetDurationMs': 360000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF15',\n", " 'controlId': 1105,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'La Cabanette - Col De Braus 1',\n", " 'stageId': 274,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC16',\n", " 'controlId': 1099,\n", " 'distance': 43.76,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T09:52:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T10:52:00+01:00',\n", " 'location': 'La Bollene Vesubi',\n", " 'stageId': 273,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:44:00',\n", " 'targetDurationMs': 6240000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS16',\n", " 'controlId': 1100,\n", " 'distance': 18.41,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T09:55:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T10:55:00+01:00',\n", " 'location': 'La Bollene Vesubie - Peira Cava 2',\n", " 'stageId': 273,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF16',\n", " 'controlId': 1101,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'La Bollene Vesubie - Peira Cava 2',\n", " 'stageId': 273,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Tenth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC16A',\n", " 'controlId': 1098,\n", " 'distance': 1.32,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T10:25:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T11:25:00+01:00',\n", " 'location': 'Regroup (IN)',\n", " 'stageId': 273,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:30:00',\n", " 'targetDurationMs': 1800000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'}],\n", " 'itineraryLegId': 49,\n", " 'itinerarySectionId': 112,\n", " 'name': 'Section 7',\n", " 'order': 7,\n", " 'stages': [{'code': 'SS14',\n", " 'distance': 18.41,\n", " 'eventId': 26,\n", " 'name': 'La Bollene Vesubie - Peira Cava 1',\n", " 'number': 14,\n", " 'stageId': 275,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'},\n", " {'code': 'SS15',\n", " 'distance': 13.58,\n", " 'eventId': 26,\n", " 'name': 'La Cabanette - Col de Braus 1',\n", " 'number': 15,\n", " 'stageId': 274,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'},\n", " {'code': 'SS16',\n", " 'distance': 18.41,\n", " 'eventId': 26,\n", " 'name': 'La Bollene Vesubie - Peira Cava 2',\n", " 'number': 16,\n", " 'stageId': 273,\n", " 'stageType': 'SpecialStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Tenth'}]},\n", " {'controls': [{'code': 'TC16B',\n", " 'controlId': 1097,\n", " 'distance': 0.17,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T11:10:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T12:10:00+01:00',\n", " 'location': 'Regroup (OUT)',\n", " 'stageId': 273,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:45:00',\n", " 'targetDurationMs': 2700000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC17',\n", " 'controlId': 1094,\n", " 'distance': 1.94,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T11:15:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T12:15:00+01:00',\n", " 'location': 'La Cabanette',\n", " 'stageId': 288,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:15:00',\n", " 'targetDurationMs': 900000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'SS17',\n", " 'controlId': 1095,\n", " 'distance': 13.58,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T11:18:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T12:18:00+01:00',\n", " 'location': 'La Cabanette - Col De Braus 2 (PS)',\n", " 'stageId': 288,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:03:00',\n", " 'targetDurationMs': 180000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'StageStart'},\n", " {'code': 'SF17',\n", " 'controlId': 1096,\n", " 'distance': None,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': None,\n", " 'firstCarDueDateTimeLocal': None,\n", " 'location': 'La Cabanette - Col De Braus 2 (PS)',\n", " 'stageId': 288,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:00:00',\n", " 'targetDurationMs': 0,\n", " 'timingPrecision': 'Thousandth',\n", " 'type': 'FlyingFinish'},\n", " {'code': 'TC17A',\n", " 'controlId': 1082,\n", " 'distance': 40.02,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T12:35:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T13:35:00+01:00',\n", " 'location': 'Technical Zone (IN)',\n", " 'stageId': 288,\n", " 'status': 'Completed',\n", " 'targetDuration': '01:30:00',\n", " 'targetDurationMs': 5400000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'},\n", " {'code': 'TC17B',\n", " 'controlId': 1118,\n", " 'distance': 0.1,\n", " 'eventId': 26,\n", " 'firstCarDueDateTime': '2018-01-28T12:43:00',\n", " 'firstCarDueDateTimeLocal': '2018-01-28T13:43:00+01:00',\n", " 'location': 'Technical Zone (IN) - Parce Ferme (OUT)',\n", " 'stageId': 288,\n", " 'status': 'Completed',\n", " 'targetDuration': '00:10:00',\n", " 'targetDurationMs': 600000,\n", " 'timingPrecision': 'Minute',\n", " 'type': 'TimeControl'}],\n", " 'itineraryLegId': 49,\n", " 'itinerarySectionId': 113,\n", " 'name': 'Section 8',\n", " 'order': 8,\n", " 'stages': [{'code': 'SS17',\n", " 'distance': 13.58,\n", " 'eventId': 26,\n", " 'name': 'La Cabanette - Col de Braus 2 (PS) ',\n", " 'number': 17,\n", " 'stageId': 288,\n", " 'stageType': 'PowerStage',\n", " 'status': 'Completed',\n", " 'timingPrecision': 'Thousandth'}]}],\n", " 'legDate': '2018-01-28',\n", " 'name': 'Sunday 28th January 2018',\n", " 'order': 4,\n", " 'startListId': 73,\n", " 'status': 'Running'}],\n", " 'name': 'Itinerary',\n", " 'priority': 0}" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "itinerary_json" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
eventIditineraryIdnamepriority
02631Itinerary0
\n", "
" ], "text/plain": [ " eventId itineraryId name priority\n", "0 26 31 Itinerary 0" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from pandas.io.json import json_normalize\n", "\n", "itinerary_event = json_normalize(itinerary_json).drop('itineraryLegs', axis=1)\n", "itinerary_event" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
itineraryIditineraryLegIdlegDatenameorderstartListIdstatuseventId
031462018-01-25Thursday 25th January 2018166Running26
131472018-01-26Friday 26th January 2018268Running26
231482018-01-27Saturday 27th January 2018370Running26
331492018-01-28Sunday 28th January 2018473Running26
\n", "
" ], "text/plain": [ " itineraryId itineraryLegId legDate name order \\\n", "0 31 46 2018-01-25 Thursday 25th January 2018 1 \n", "1 31 47 2018-01-26 Friday 26th January 2018 2 \n", "2 31 48 2018-01-27 Saturday 27th January 2018 3 \n", "3 31 49 2018-01-28 Sunday 28th January 2018 4 \n", "\n", " startListId status eventId \n", "0 66 Running 26 \n", "1 68 Running 26 \n", "2 70 Running 26 \n", "3 73 Running 26 " ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "itinerary_legs = json_normalize(itinerary_json, record_path='itineraryLegs',\n", " meta='eventId').drop('itinerarySections', axis=1)\n", "#?don't need eventId?\n", "itinerary_legs" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
itineraryLegIditinerarySectionIdnameordereventId
046106Section 1126
147107Section 2226
247108Section 3326
348109Section 4426
448110Section 5526
548111Section 6626
649112Section 7726
749113Section 8826
\n", "
" ], "text/plain": [ " itineraryLegId itinerarySectionId name order eventId\n", "0 46 106 Section 1 1 26\n", "1 47 107 Section 2 2 26\n", "2 47 108 Section 3 3 26\n", "3 48 109 Section 4 4 26\n", "4 48 110 Section 5 5 26\n", "5 48 111 Section 6 6 26\n", "6 49 112 Section 7 7 26\n", "7 49 113 Section 8 8 26" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "itinerary_sections = json_normalize(itinerary_json, ['itineraryLegs', 'itinerarySections'],\n", " meta='eventId').drop(['stages','controls'],axis=1)\n", "#?don't need eventId?\n", "itinerary_sections" ] }, { "cell_type": "code", "execution_count": 163, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
codedistanceeventIdnamenumberstageIdstageTypestatustimingPrecisionitineraryLegs.itinerarySections.itinerarySectionId
0SS136.6926Thoard - Sisteron1289SpecialStageCompletedTenth106
1SS225.4926Bayons - Breziers 12287SpecialStageCompletedTenth106
2SS326.7226Vitrolles - Oze 13286SpecialStageCompletedTenth107
3SS430.5426Roussieux - Eygalayes 14285SpecialStageCompletedTenth107
4SS515.1826Vaumeilh - Claret 15284SpecialStageCompletedTenth107
5SS626.7226Vitrolles - Oze 26283SpecialStageCompletedTenth108
6SS730.5426Roussieux - Eygalayes 27282SpecialStageCompletedTenth108
7SS815.1826Vaumeilh - Claret 28281SpecialStageCompletedTenth108
8SS929.1626Agnieres En Devoluy - Corps 19280SpecialStageCompletedTenth109
9SS1016.8726St Leger Les Melezes - La Batie Neuve 110279SpecialStageCompletedTenth109
10SS1129.1626Agnieres En Devoluy - Corps 211278SpecialStageCompletedTenth110
11SS1216.8726St Leger Les Melezes - La Batie Neuve 212277SpecialStageCompletedTenth110
12SS1325.4926Bayons - Breziers 213276SpecialStageCompletedTenth111
13SS1418.4126La Bollene Vesubie - Peira Cava 114275SpecialStageCompletedTenth112
14SS1513.5826La Cabanette - Col de Braus 115274SpecialStageCompletedTenth112
15SS1618.4126La Bollene Vesubie - Peira Cava 216273SpecialStageCompletedTenth112
16SS1713.5826La Cabanette - Col de Braus 2 (PS)17288PowerStageCompletedThousandth113
\n", "
" ], "text/plain": [ " code distance eventId name number \\\n", "0 SS1 36.69 26 Thoard - Sisteron 1 \n", "1 SS2 25.49 26 Bayons - Breziers 1 2 \n", "2 SS3 26.72 26 Vitrolles - Oze 1 3 \n", "3 SS4 30.54 26 Roussieux - Eygalayes 1 4 \n", "4 SS5 15.18 26 Vaumeilh - Claret 1 5 \n", "5 SS6 26.72 26 Vitrolles - Oze 2 6 \n", "6 SS7 30.54 26 Roussieux - Eygalayes 2 7 \n", "7 SS8 15.18 26 Vaumeilh - Claret 2 8 \n", "8 SS9 29.16 26 Agnieres En Devoluy - Corps 1 9 \n", "9 SS10 16.87 26 St Leger Les Melezes - La Batie Neuve 1 10 \n", "10 SS11 29.16 26 Agnieres En Devoluy - Corps 2 11 \n", "11 SS12 16.87 26 St Leger Les Melezes - La Batie Neuve 2 12 \n", "12 SS13 25.49 26 Bayons - Breziers 2 13 \n", "13 SS14 18.41 26 La Bollene Vesubie - Peira Cava 1 14 \n", "14 SS15 13.58 26 La Cabanette - Col de Braus 1 15 \n", "15 SS16 18.41 26 La Bollene Vesubie - Peira Cava 2 16 \n", "16 SS17 13.58 26 La Cabanette - Col de Braus 2 (PS) 17 \n", "\n", " stageId stageType status timingPrecision \\\n", "0 289 SpecialStage Completed Tenth \n", "1 287 SpecialStage Completed Tenth \n", "2 286 SpecialStage Completed Tenth \n", "3 285 SpecialStage Completed Tenth \n", "4 284 SpecialStage Completed Tenth \n", "5 283 SpecialStage Completed Tenth \n", "6 282 SpecialStage Completed Tenth \n", "7 281 SpecialStage Completed Tenth \n", "8 280 SpecialStage Completed Tenth \n", "9 279 SpecialStage Completed Tenth \n", "10 278 SpecialStage Completed Tenth \n", "11 277 SpecialStage Completed Tenth \n", "12 276 SpecialStage Completed Tenth \n", "13 275 SpecialStage Completed Tenth \n", "14 274 SpecialStage Completed Tenth \n", "15 273 SpecialStage Completed Tenth \n", "16 288 PowerStage Completed Thousandth \n", "\n", " itineraryLegs.itinerarySections.itinerarySectionId \n", "0 106 \n", "1 106 \n", "2 107 \n", "3 107 \n", "4 107 \n", "5 108 \n", "6 108 \n", "7 108 \n", "8 109 \n", "9 109 \n", "10 110 \n", "11 110 \n", "12 111 \n", "13 112 \n", "14 112 \n", "15 112 \n", "16 113 " ] }, "execution_count": 163, "metadata": {}, "output_type": "execute_result" } ], "source": [ "json_normalize(itinerary_json, ['itineraryLegs', 'itinerarySections', 'stages'],\n", " meta=[['itineraryLegs','itinerarySections','itinerarySectionId']]\n", " )#.drop(['controls'],axis=1)\n" ] }, { "cell_type": "code", "execution_count": 167, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
codedistanceeventIdnamenumberstageIdstageTypestatustimingPrecisionitineraryLegIditinerarySections.itinerarySectionId
0SS136.6926Thoard - Sisteron1289SpecialStageCompletedTenth46106
1SS225.4926Bayons - Breziers 12287SpecialStageCompletedTenth46106
2SS326.7226Vitrolles - Oze 13286SpecialStageCompletedTenth47107
3SS430.5426Roussieux - Eygalayes 14285SpecialStageCompletedTenth47107
4SS515.1826Vaumeilh - Claret 15284SpecialStageCompletedTenth47107
5SS626.7226Vitrolles - Oze 26283SpecialStageCompletedTenth47108
6SS730.5426Roussieux - Eygalayes 27282SpecialStageCompletedTenth47108
7SS815.1826Vaumeilh - Claret 28281SpecialStageCompletedTenth47108
8SS929.1626Agnieres En Devoluy - Corps 19280SpecialStageCompletedTenth48109
9SS1016.8726St Leger Les Melezes - La Batie Neuve 110279SpecialStageCompletedTenth48109
\n", "
" ], "text/plain": [ " code distance eventId name number \\\n", "0 SS1 36.69 26 Thoard - Sisteron 1 \n", "1 SS2 25.49 26 Bayons - Breziers 1 2 \n", "2 SS3 26.72 26 Vitrolles - Oze 1 3 \n", "3 SS4 30.54 26 Roussieux - Eygalayes 1 4 \n", "4 SS5 15.18 26 Vaumeilh - Claret 1 5 \n", "5 SS6 26.72 26 Vitrolles - Oze 2 6 \n", "6 SS7 30.54 26 Roussieux - Eygalayes 2 7 \n", "7 SS8 15.18 26 Vaumeilh - Claret 2 8 \n", "8 SS9 29.16 26 Agnieres En Devoluy - Corps 1 9 \n", "9 SS10 16.87 26 St Leger Les Melezes - La Batie Neuve 1 10 \n", "\n", " stageId stageType status timingPrecision itineraryLegId \\\n", "0 289 SpecialStage Completed Tenth 46 \n", "1 287 SpecialStage Completed Tenth 46 \n", "2 286 SpecialStage Completed Tenth 47 \n", "3 285 SpecialStage Completed Tenth 47 \n", "4 284 SpecialStage Completed Tenth 47 \n", "5 283 SpecialStage Completed Tenth 47 \n", "6 282 SpecialStage Completed Tenth 47 \n", "7 281 SpecialStage Completed Tenth 47 \n", "8 280 SpecialStage Completed Tenth 48 \n", "9 279 SpecialStage Completed Tenth 48 \n", "\n", " itinerarySections.itinerarySectionId \n", "0 106 \n", "1 106 \n", "2 107 \n", "3 107 \n", "4 107 \n", "5 108 \n", "6 108 \n", "7 108 \n", "8 109 \n", "9 109 " ] }, "execution_count": 167, "metadata": {}, "output_type": "execute_result" } ], "source": [ "itinerary_stages=json_normalize(itinerary_json['itineraryLegs'],\n", " ['itinerarySections','stages'],\n", " meta=['itineraryLegId',['itinerarySections','itinerarySectionId']])\n", "itinerary_stages.head(10)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "meta['stages']=itinerary_stages['stageId'].tolist()" ] }, { "cell_type": "code", "execution_count": 168, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
codecontrolIddistanceeventIdfirstCarDueDateTimefirstCarDueDateTimeLocallocationstageIdstatustargetDurationtargetDurationMstimingPrecisiontypeitineraryLegIditinerarySections.itinerarySectionId
0TC01066NaN262018-01-25T16:50:002018-01-25T17:50:00+01:00Monaco - Depart Day 1-1Completed00:00:000MinuteTimeControl46106
1TC11133192.71262018-01-25T20:40:002018-01-25T21:40:00+01:00Thoard289Completed03:50:0013800000MinuteTimeControl46106
2SS1113436.69262018-01-25T20:43:002018-01-25T21:43:00+01:00Thoard - Sisteron289Completed00:03:00180000MinuteStageStart46106
3SF11135NaN26NoneNoneThoard - Sisteron289Completed00:00:000TenthFlyingFinish46106
4TC2112330.71262018-01-25T21:48:002018-01-25T22:48:00+01:00Bayons287Completed01:05:003900000MinuteTimeControl46106
\n", "
" ], "text/plain": [ " code controlId distance eventId firstCarDueDateTime \\\n", "0 TC0 1066 NaN 26 2018-01-25T16:50:00 \n", "1 TC1 1133 192.71 26 2018-01-25T20:40:00 \n", "2 SS1 1134 36.69 26 2018-01-25T20:43:00 \n", "3 SF1 1135 NaN 26 None \n", "4 TC2 1123 30.71 26 2018-01-25T21:48:00 \n", "\n", " firstCarDueDateTimeLocal location stageId status \\\n", "0 2018-01-25T17:50:00+01:00 Monaco - Depart Day 1 -1 Completed \n", "1 2018-01-25T21:40:00+01:00 Thoard 289 Completed \n", "2 2018-01-25T21:43:00+01:00 Thoard - Sisteron 289 Completed \n", "3 None Thoard - Sisteron 289 Completed \n", "4 2018-01-25T22:48:00+01:00 Bayons 287 Completed \n", "\n", " targetDuration targetDurationMs timingPrecision type \\\n", "0 00:00:00 0 Minute TimeControl \n", "1 03:50:00 13800000 Minute TimeControl \n", "2 00:03:00 180000 Minute StageStart \n", "3 00:00:00 0 Tenth FlyingFinish \n", "4 01:05:00 3900000 Minute TimeControl \n", "\n", " itineraryLegId itinerarySections.itinerarySectionId \n", "0 46 106 \n", "1 46 106 \n", "2 46 106 \n", "3 46 106 \n", "4 46 106 " ] }, "execution_count": 168, "metadata": {}, "output_type": "execute_result" } ], "source": [ "itinerary_controls=json_normalize(itinerary_json['itineraryLegs'], \n", " ['itinerarySections','controls'] ,\n", " meta=['itineraryLegId',['itinerarySections','itinerarySectionId']])\n", "itinerary_controls['stageId'] = itinerary_controls['stageId'].fillna(-1).astype(int)\n", "itinerary_controls.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Startlists" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "startlists_json=requests.get( url_base.format(stub=startlists_stub.format(**meta) ) ).json()\n", "#startlists_json" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
codriver.abbvNamecodriver.codecodriver.country.countryIdcodriver.country.iso2codriver.country.iso3codriver.country.namecodriver.countryIdcodriver.firstNamecodriver.fullNamecodriver.lastName...groupIdidentifiermanufacturer.logoFilenamemanufacturer.manufacturerIdmanufacturer.namemanufacturerIdprioritystatustyreManufacturervehicleModel
0J. INGRASSIAING76FRFRAFrance76JulienJulien INGRASSIAINGRASSIA...101ford26Ford26P1EntryMichelinFIESTA WRC
1D. BARRITTBAR235GBGBRUnited Kingdom of Great Britain and Northern I...235DanielDaniel BARRITTBARRITT...102ford26Ford26P1EntryMichelinFIESTA WRC
2X. PANSERIPAN76FRFRAFrance76XavierXavier PANSERIPANSERI...103ford26Ford26P1EntryMichelinFIESTA WRC
3A. JAEGERJAE166NONORNorway166AndersAnders JAEGERJAEGER...104hyundai33Hyundai33P1RejoinedMichelini20 WRC
4N. GILSOULGIL22BEBELBelgium22NicolasNicolas GILSOULGILSOUL...105hyundai33Hyundai33P1EntryMichelini20 WRC
\n", "

5 rows × 43 columns

\n", "
" ], "text/plain": [ " codriver.abbvName codriver.code codriver.country.countryId \\\n", "0 J. INGRASSIA ING 76 \n", "1 D. BARRITT BAR 235 \n", "2 X. PANSERI PAN 76 \n", "3 A. JAEGER JAE 166 \n", "4 N. GILSOUL GIL 22 \n", "\n", " codriver.country.iso2 codriver.country.iso3 \\\n", "0 FR FRA \n", "1 GB GBR \n", "2 FR FRA \n", "3 NO NOR \n", "4 BE BEL \n", "\n", " codriver.country.name codriver.countryId \\\n", "0 France 76 \n", "1 United Kingdom of Great Britain and Northern I... 235 \n", "2 France 76 \n", "3 Norway 166 \n", "4 Belgium 22 \n", "\n", " codriver.firstName codriver.fullName codriver.lastName ... \\\n", "0 Julien Julien INGRASSIA INGRASSIA ... \n", "1 Daniel Daniel BARRITT BARRITT ... \n", "2 Xavier Xavier PANSERI PANSERI ... \n", "3 Anders Anders JAEGER JAEGER ... \n", "4 Nicolas Nicolas GILSOUL GILSOUL ... \n", "\n", " groupId identifier manufacturer.logoFilename manufacturer.manufacturerId \\\n", "0 10 1 ford 26 \n", "1 10 2 ford 26 \n", "2 10 3 ford 26 \n", "3 10 4 hyundai 33 \n", "4 10 5 hyundai 33 \n", "\n", " manufacturer.name manufacturerId priority status tyreManufacturer \\\n", "0 Ford 26 P1 Entry Michelin \n", "1 Ford 26 P1 Entry Michelin \n", "2 Ford 26 P1 Entry Michelin \n", "3 Hyundai 33 P1 Rejoined Michelin \n", "4 Hyundai 33 P1 Entry Michelin \n", "\n", " vehicleModel \n", "0 FIESTA WRC \n", "1 FIESTA WRC \n", "2 FIESTA WRC \n", "3 i20 WRC \n", "4 i20 WRC \n", "\n", "[5 rows x 43 columns]" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "startlists = json_normalize(startlists_json).drop('eventClasses', axis=1)\n", "startlists.head()" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['codriver.abbvName', 'codriver.code', 'codriver.country.countryId',\n", " 'codriver.country.iso2', 'codriver.country.iso3',\n", " 'codriver.country.name', 'codriver.countryId', 'codriver.firstName',\n", " 'codriver.fullName', 'codriver.lastName', 'codriver.personId',\n", " 'codriverId', 'driver.abbvName', 'driver.code',\n", " 'driver.country.countryId', 'driver.country.iso2',\n", " 'driver.country.iso3', 'driver.country.name', 'driver.countryId',\n", " 'driver.firstName', 'driver.fullName', 'driver.lastName',\n", " 'driver.personId', 'driverId', 'eligibility', 'entrant.entrantId',\n", " 'entrant.logoFilename', 'entrant.name', 'entrantId', 'entryId',\n", " 'eventId', 'group.groupId', 'group.name', 'groupId', 'identifier',\n", " 'manufacturer.logoFilename', 'manufacturer.manufacturerId',\n", " 'manufacturer.name', 'manufacturerId', 'priority', 'status',\n", " 'tyreManufacturer', 'vehicleModel'],\n", " dtype='object')" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "startlists.columns" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
eventClassIdeventIdnameentryId
010326RC11483
110326RC11484
210326RC11485
310326RC11486
410326RC11487
\n", "
" ], "text/plain": [ " eventClassId eventId name entryId\n", "0 103 26 RC1 1483\n", "1 103 26 RC1 1484\n", "2 103 26 RC1 1485\n", "3 103 26 RC1 1486\n", "4 103 26 RC1 1487" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "startlist_classes = json_normalize(startlists_json,['eventClasses'], 'entryId' )\n", "startlist_classes.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Penalties" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "penalties_json=requests.get( url_base.format(stub=penalties_stub.format(**meta) ) ).json()\n", "#penalties_json" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
controlIdentryIdpenaltyDurationpenaltyDurationMspenaltyIdreason
011231496PT40S40000384 MN LATE
111231493PT10S10000391 MN LATE
211231524PT30S30000403 MN LATE
311231516PT20S20000412 MN LATE
411231517PT30S30000423 MN LATE
\n", "
" ], "text/plain": [ " controlId entryId penaltyDuration penaltyDurationMs penaltyId \\\n", "0 1123 1496 PT40S 40000 38 \n", "1 1123 1493 PT10S 10000 39 \n", "2 1123 1524 PT30S 30000 40 \n", "3 1123 1516 PT20S 20000 41 \n", "4 1123 1517 PT30S 30000 42 \n", "\n", " reason \n", "0 4 MN LATE \n", "1 1 MN LATE \n", "2 3 MN LATE \n", "3 2 MN LATE \n", "4 3 MN LATE " ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "penalties = json_normalize(penalties_json)\n", "penalties.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Retirements" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "retirements_json=requests.get( url_base.format(stub=retirements_stub.format(**meta) ) ).json()\n", "#retirements_json" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
controlIdentryIdreasonretirementDateTimeretirementDateTimeLocalretirementIdstatus
011351518Mechanical2018-01-25T21:40:00Z2018-01-25T22:40:00+01:0017Rejoined
111351538Off Road2018-01-25T22:00:00Z2018-01-25T23:00:00+01:0018Rejoined
211351546Mechanical2018-01-25T22:05:00Z2018-01-25T23:05:00+01:0019Rejoined
311231528Mechanical2018-01-25T23:15:00Z2018-01-26T00:15:00+01:0020Rejoined
411231534Mechanical2018-01-25T23:15:00Z2018-01-26T00:15:00+01:0021Rejoined
\n", "
" ], "text/plain": [ " controlId entryId reason retirementDateTime \\\n", "0 1135 1518 Mechanical 2018-01-25T21:40:00Z \n", "1 1135 1538 Off Road 2018-01-25T22:00:00Z \n", "2 1135 1546 Mechanical 2018-01-25T22:05:00Z \n", "3 1123 1528 Mechanical 2018-01-25T23:15:00Z \n", "4 1123 1534 Mechanical 2018-01-25T23:15:00Z \n", "\n", " retirementDateTimeLocal retirementId status \n", "0 2018-01-25T22:40:00+01:00 17 Rejoined \n", "1 2018-01-25T23:00:00+01:00 18 Rejoined \n", "2 2018-01-25T23:05:00+01:00 19 Rejoined \n", "3 2018-01-26T00:15:00+01:00 20 Rejoined \n", "4 2018-01-26T00:15:00+01:00 21 Rejoined " ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "retirements = json_normalize(retirements_json)\n", "retirements.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Stagewinners" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "scrolled": true }, "outputs": [], "source": [ "stagewinners_json=requests.get( url_base.format(stub=stagewinners_stub.format(**meta) ) ).json()\n", "#stagewinners_json" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
elapsedDurationelapsedDurationMsentryIdstageIdstageName
000:14:53.20000008932001483287Bayons - Breziers 1
100:23:16.600000013966001483289Thoard - Sisteron
200:08:42.60000005226001484284Vaumeilh - Claret 1
300:18:25.300000011053001483285Roussieux - Eygalayes 1
400:16:32.30000009923001490286Vitrolles - Oze 1
\n", "
" ], "text/plain": [ " elapsedDuration elapsedDurationMs entryId stageId \\\n", "0 00:14:53.2000000 893200 1483 287 \n", "1 00:23:16.6000000 1396600 1483 289 \n", "2 00:08:42.6000000 522600 1484 284 \n", "3 00:18:25.3000000 1105300 1483 285 \n", "4 00:16:32.3000000 992300 1490 286 \n", "\n", " stageName \n", "0 Bayons - Breziers 1 \n", "1 Thoard - Sisteron \n", "2 Vaumeilh - Claret 1 \n", "3 Roussieux - Eygalayes 1 \n", "4 Vitrolles - Oze 1 " ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stagewinners = json_normalize(stagewinners_json)\n", "stagewinners.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Stage Iterator\n", "\n", "TO DO: For following stage based tables, create a generic stage iterator function." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Overall" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
diffFirstdiffFirstMsdiffPrevdiffPrevMsentryIdpenaltyTimepenaltyTimeMspositionstageTimestageTimeMstotalTimetotalTimeMsstageId
0PT0S0PT0S01483PT0S01PT23M16.6S1396600PT23M16.6S1396600289
1PT7.7S7700PT7.7S77001486PT0S02PT23M24.3S1404300PT23M24.3S1404300289
2PT19.4S19400PT11.7S117001491PT0S03PT23M36S1416000PT23M36S1416000289
3PT19.7S19700PT0.3S3001488PT0S04PT23M36.3S1416300PT23M36.3S1416300289
4PT24.6S24600PT4.9S49001493PT0S05PT23M41.2S1421200PT23M41.2S1421200289
\n", "
" ], "text/plain": [ " diffFirst diffFirstMs diffPrev diffPrevMs entryId penaltyTime \\\n", "0 PT0S 0 PT0S 0 1483 PT0S \n", "1 PT7.7S 7700 PT7.7S 7700 1486 PT0S \n", "2 PT19.4S 19400 PT11.7S 11700 1491 PT0S \n", "3 PT19.7S 19700 PT0.3S 300 1488 PT0S \n", "4 PT24.6S 24600 PT4.9S 4900 1493 PT0S \n", "\n", " penaltyTimeMs position stageTime stageTimeMs totalTime totalTimeMs \\\n", "0 0 1 PT23M16.6S 1396600 PT23M16.6S 1396600 \n", "1 0 2 PT23M24.3S 1404300 PT23M24.3S 1404300 \n", "2 0 3 PT23M36S 1416000 PT23M36S 1416000 \n", "3 0 4 PT23M36.3S 1416300 PT23M36.3S 1416300 \n", "4 0 5 PT23M41.2S 1421200 PT23M41.2S 1421200 \n", "\n", " stageId \n", "0 289 \n", "1 289 \n", "2 289 \n", "3 289 \n", "4 289 " ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "meta2=meta\n", "stage_overall = pd.DataFrame()\n", "for stageId in meta['stages']:\n", " meta2['stageId']=stageId\n", " _stage_overall_json=requests.get( url_base.format(stub=overall_stub.format(**meta2) ) ).json()\n", " _stage_overall = json_normalize(_stage_overall_json)\n", " _stage_overall['stageId'] = stageId\n", " stage_overall = pd.concat([stage_overall, _stage_overall])\n", "stage_overall.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Split Times" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
elapsedDurationelapsedDurationMsentryIdsplitDateTimesplitDateTimeLocalsplitPointIdsplitPointTimeIdstageTimeDurationstageTimeDurationMsstartDateTimestartDateTimeLocalstageId
0PT23M18.17S139817014872018-01-25T21:08:18.17Z2018-01-25T22:08:18.17+01:005771333800:27:33.40000001653400.02018-01-25T20:45:002018-01-25T21:45:00+01:00289
1PT19M47.803S118780314892018-01-25T21:08:47.803Z2018-01-25T22:08:47.803+01:005771333900:24:05.50000001445500.02018-01-25T20:49:002018-01-25T21:49:00+01:00289
2PT19M37.267S117726714902018-01-25T21:06:37.267Z2018-01-25T22:06:37.267+01:005771334100:23:54.50000001434500.02018-01-25T20:47:002018-01-25T21:47:00+01:00289
3PT19M20.088S116008814882018-01-25T21:12:20.088Z2018-01-25T22:12:20.088+01:005771334900:23:36.30000001416300.02018-01-25T20:53:002018-01-25T21:53:00+01:00289
4PT22M42.864S136286414842018-01-25T21:13:42.864Z2018-01-25T22:13:42.864+01:005771335200:27:04.60000001624600.02018-01-25T20:51:002018-01-25T21:51:00+01:00289
\n", "
" ], "text/plain": [ " elapsedDuration elapsedDurationMs entryId splitDateTime \\\n", "0 PT23M18.17S 1398170 1487 2018-01-25T21:08:18.17Z \n", "1 PT19M47.803S 1187803 1489 2018-01-25T21:08:47.803Z \n", "2 PT19M37.267S 1177267 1490 2018-01-25T21:06:37.267Z \n", "3 PT19M20.088S 1160088 1488 2018-01-25T21:12:20.088Z \n", "4 PT22M42.864S 1362864 1484 2018-01-25T21:13:42.864Z \n", "\n", " splitDateTimeLocal splitPointId splitPointTimeId \\\n", "0 2018-01-25T22:08:18.17+01:00 577 13338 \n", "1 2018-01-25T22:08:47.803+01:00 577 13339 \n", "2 2018-01-25T22:06:37.267+01:00 577 13341 \n", "3 2018-01-25T22:12:20.088+01:00 577 13349 \n", "4 2018-01-25T22:13:42.864+01:00 577 13352 \n", "\n", " stageTimeDuration stageTimeDurationMs startDateTime \\\n", "0 00:27:33.4000000 1653400.0 2018-01-25T20:45:00 \n", "1 00:24:05.5000000 1445500.0 2018-01-25T20:49:00 \n", "2 00:23:54.5000000 1434500.0 2018-01-25T20:47:00 \n", "3 00:23:36.3000000 1416300.0 2018-01-25T20:53:00 \n", "4 00:27:04.6000000 1624600.0 2018-01-25T20:51:00 \n", "\n", " startDateTimeLocal stageId \n", "0 2018-01-25T21:45:00+01:00 289 \n", "1 2018-01-25T21:49:00+01:00 289 \n", "2 2018-01-25T21:47:00+01:00 289 \n", "3 2018-01-25T21:53:00+01:00 289 \n", "4 2018-01-25T21:51:00+01:00 289 " ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "split_times=pd.DataFrame()\n", "for stageId in meta['stages']:\n", " meta2['stageId']=stageId\n", " _stage_split_times_json=requests.get( url_base.format(stub=split_times_stub.format(**meta2) ) ).json()\n", " _stage_split_times = json_normalize(_stage_split_times_json)\n", " _stage_split_times['stageId'] = stageId\n", " split_times = pd.concat([split_times, _stage_split_times])\n", "split_times.head()" ] }, { "cell_type": "code", "execution_count": 195, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
elapsedDurationelapsedDurationMsentryIdsplitDateTimesplitDateTimeLocalsplitPointIdsplitPointTimeIdstartDateTimestartDateTimeLocalstageId
0PT23M18.17S139817014872018-01-25T21:08:18.17Z2018-01-25T22:08:18.17+01:00577133382018-01-25T20:45:002018-01-25T21:45:00+01:00289
65PT19M46.543S118654314872018-01-25T21:04:46.543Z2018-01-25T22:04:46.543+01:00580133302018-01-25T20:45:002018-01-25T21:45:00+01:00289
85PT19M11.78S115178014872018-01-25T21:10:11.78Z2018-01-25T22:10:11.78+01:00580134612018-01-25T20:45:002018-01-25T21:45:00+01:00289
129PT17M27.061S104706114872018-01-25T21:02:27.061Z2018-01-25T22:02:27.061+01:00581133252018-01-25T20:45:002018-01-25T21:45:00+01:00289
191PT7M57.321S47732114872018-01-25T20:52:57.321Z2018-01-25T21:52:57.321+01:00582133182018-01-25T20:45:002018-01-25T21:45:00+01:00289
287PT4M9.425S24942514872018-01-25T20:49:09.4266667Z2018-01-25T21:49:09.4266667+01:00614134392018-01-25T20:45:002018-01-25T21:45:00+01:00289
\n", "
" ], "text/plain": [ " elapsedDuration elapsedDurationMs entryId splitDateTime \\\n", "0 PT23M18.17S 1398170 1487 2018-01-25T21:08:18.17Z \n", "65 PT19M46.543S 1186543 1487 2018-01-25T21:04:46.543Z \n", "85 PT19M11.78S 1151780 1487 2018-01-25T21:10:11.78Z \n", "129 PT17M27.061S 1047061 1487 2018-01-25T21:02:27.061Z \n", "191 PT7M57.321S 477321 1487 2018-01-25T20:52:57.321Z \n", "287 PT4M9.425S 249425 1487 2018-01-25T20:49:09.4266667Z \n", "\n", " splitDateTimeLocal splitPointId splitPointTimeId \\\n", "0 2018-01-25T22:08:18.17+01:00 577 13338 \n", "65 2018-01-25T22:04:46.543+01:00 580 13330 \n", "85 2018-01-25T22:10:11.78+01:00 580 13461 \n", "129 2018-01-25T22:02:27.061+01:00 581 13325 \n", "191 2018-01-25T21:52:57.321+01:00 582 13318 \n", "287 2018-01-25T21:49:09.4266667+01:00 614 13439 \n", "\n", " startDateTime startDateTimeLocal stageId \n", "0 2018-01-25T20:45:00 2018-01-25T21:45:00+01:00 289 \n", "65 2018-01-25T20:45:00 2018-01-25T21:45:00+01:00 289 \n", "85 2018-01-25T20:45:00 2018-01-25T21:45:00+01:00 289 \n", "129 2018-01-25T20:45:00 2018-01-25T21:45:00+01:00 289 \n", "191 2018-01-25T20:45:00 2018-01-25T21:45:00+01:00 289 \n", "287 2018-01-25T20:45:00 2018-01-25T21:45:00+01:00 289 " ] }, "execution_count": 195, "metadata": {}, "output_type": "execute_result" } ], "source": [ "split_times[(split_times['entryId']==1487) & (split_times['stageId']==289)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Stage Times - Stage" ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
diffFirstdiffFirstMsdiffPrevdiffPrevMselapsedDurationelapsedDurationMsentryIdpositionsourcestageIdstageTimeIdstatus
000:00:000.000:00:000.000:23:16.60000001396600.014831Default2896639Completed
100:00:07.70000007700.000:00:07.70000007700.000:23:24.30000001404300.014862Default2896657Completed
200:00:19.400000019400.000:00:11.700000011700.000:23:361416000.014913Assessed2896655Completed
300:00:19.700000019700.000:00:00.3000000300.000:23:36.30000001416300.014884Default2896649Completed
400:00:24.600000024600.000:00:04.90000004900.000:23:41.20000001421200.014935Default2896653Completed
\n", "
" ], "text/plain": [ " diffFirst diffFirstMs diffPrev diffPrevMs \\\n", "0 00:00:00 0.0 00:00:00 0.0 \n", "1 00:00:07.7000000 7700.0 00:00:07.7000000 7700.0 \n", "2 00:00:19.4000000 19400.0 00:00:11.7000000 11700.0 \n", "3 00:00:19.7000000 19700.0 00:00:00.3000000 300.0 \n", "4 00:00:24.6000000 24600.0 00:00:04.9000000 4900.0 \n", "\n", " elapsedDuration elapsedDurationMs entryId position source stageId \\\n", "0 00:23:16.6000000 1396600.0 1483 1 Default 289 \n", "1 00:23:24.3000000 1404300.0 1486 2 Default 289 \n", "2 00:23:36 1416000.0 1491 3 Assessed 289 \n", "3 00:23:36.3000000 1416300.0 1488 4 Default 289 \n", "4 00:23:41.2000000 1421200.0 1493 5 Default 289 \n", "\n", " stageTimeId status \n", "0 6639 Completed \n", "1 6657 Completed \n", "2 6655 Completed \n", "3 6649 Completed \n", "4 6653 Completed " ] }, "execution_count": 111, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stage_times_stage=pd.DataFrame()\n", "for stageId in meta['stages']:\n", " meta2['stageId']=stageId\n", " _stage_times_stage_json=requests.get( url_base.format(stub=stage_times_stage_stub.format(**meta2) ) ).json()\n", " _stage_times_stage = json_normalize(_stage_times_stage_json)\n", " _stage_times_stage['stageId'] = stageId\n", " stage_times_stage = pd.concat([stage_times_stage, _stage_times_stage])\n", "stage_times_stage.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Stage Times - Overall" ] }, { "cell_type": "code", "execution_count": 112, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
diffFirstdiffFirstMsdiffPrevdiffPrevMsentryIdpenaltyTimepenaltyTimeMspositionstageTimestageTimeMstotalTimetotalTimeMsstageId
0PT0S0PT0S01483PT0S01PT23M16.6S1396600PT23M16.6S1396600289
1PT7.7S7700PT7.7S77001486PT0S02PT23M24.3S1404300PT23M24.3S1404300289
2PT19.4S19400PT11.7S117001491PT0S03PT23M36S1416000PT23M36S1416000289
3PT24.6S24600PT5.2S52001493PT0S04PT23M41.2S1421200PT23M41.2S1421200289
4PT37.9S37900PT13.3S133001490PT0S05PT23M54.5S1434500PT23M54.5S1434500289
\n", "
" ], "text/plain": [ " diffFirst diffFirstMs diffPrev diffPrevMs entryId penaltyTime \\\n", "0 PT0S 0 PT0S 0 1483 PT0S \n", "1 PT7.7S 7700 PT7.7S 7700 1486 PT0S \n", "2 PT19.4S 19400 PT11.7S 11700 1491 PT0S \n", "3 PT24.6S 24600 PT5.2S 5200 1493 PT0S \n", "4 PT37.9S 37900 PT13.3S 13300 1490 PT0S \n", "\n", " penaltyTimeMs position stageTime stageTimeMs totalTime totalTimeMs \\\n", "0 0 1 PT23M16.6S 1396600 PT23M16.6S 1396600 \n", "1 0 2 PT23M24.3S 1404300 PT23M24.3S 1404300 \n", "2 0 3 PT23M36S 1416000 PT23M36S 1416000 \n", "3 0 4 PT23M41.2S 1421200 PT23M41.2S 1421200 \n", "4 0 5 PT23M54.5S 1434500 PT23M54.5S 1434500 \n", "\n", " stageId \n", "0 289 \n", "1 289 \n", "2 289 \n", "3 289 \n", "4 289 " ] }, "execution_count": 112, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stage_times_overall=pd.DataFrame()\n", "for stageId in meta['stages']:\n", " meta2['stageId']=stageId\n", " _stage_times_overall_json=requests.get( url_base.format(stub=stage_times_overall_stub.format(**meta2) ) ).json()\n", " _stage_times_overall = json_normalize(_stage_times_overall_json)\n", " _stage_times_overall['stageId'] = stageId\n", " stage_times_overall = pd.concat([stage_times_overall, _stage_times_overall])\n", "stage_times_overall.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Championships" ] }, { "cell_type": "code", "execution_count": 241, "metadata": {}, "outputs": [], "source": [ "#http://www.wrc.com/en/wrc/results/championship-standings/page/4176----.html\n", "championshipClasses = { 'WRC': {\n", " 'Driver': '6',\n", " 'Co-Driver': '7',\n", " 'Manufacturers': '8'\n", " },\n", " 'WRC 2': {\n", " 'Driver': '10',\n", " 'Co-Driver': '11',\n", " 'Manufacturers': '9'\n", " },\n", " 'WRC 3': {\n", " 'Driver': '13',\n", " 'Co-Driver': '14',\n", " 'Manufacturers': '12'\n", " },\n", " 'JWRC': {\n", " 'Driver': '15',\n", " 'Co-Driver': '16'\n", " }\n", " }" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can extract the javascript that declares the championship codes from the HTML page and convert it to a Python `dict`." ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [], "source": [ "import json\n", "import re\n", "import requests\n", "\n", "url='http://www.wrc.com/en/wrc/results/championship-standings/page/4176----.html'\n", "\n", "html2=requests.get(url).text" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'JWRC': {'Co-Driver': '16', 'Driver': '15'},\n", " 'WRC': {'Co-Driver': '7', 'Driver': '6', 'Manufacturers': '8'},\n", " 'WRC2': {'Co-Driver': '11', 'Driver': '10', 'Manufacturers': '9'},\n", " 'WRC3': {'Co-Driver': '14', 'Driver': '13', 'Manufacturers': '12'}}" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = re.search(\"var championshipClasses = (.*?);\", html2, re.DOTALL)\n", "mm=m.group(1).replace('\\n','').replace(\"'\",'\"')\n", "d=json.loads(mm)\n", "#https://stackoverflow.com/a/35758583/454773\n", "championshipClasses={k.replace(' ', ''): v for k, v in d.items()}\n", "championshipClasses" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [], "source": [ "drivers = 6\n", "codrivers = 7\n", "manufacturer = 8\n", "\n", "championships={}\n", "\n", "champ_num = drivers" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [], "source": [ "meta2['championshipId']= champ_num\n", "championship_json=requests.get( url_base.format(stub=championship_stub.format(**meta2) ) ).json()\n", "#championship_json" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
championshipIdfieldFiveDescriptionfieldFourDescriptionfieldOneDescriptionfieldThreeDescriptionfieldTwoDescriptionnameseasonIdtype
06TyreManufacturerManufacturerFirstNameCountryISO3LastNameFIA World Rally Championship for Drivers1Person
\n", "
" ], "text/plain": [ " championshipId fieldFiveDescription fieldFourDescription \\\n", "0 6 TyreManufacturer Manufacturer \n", "\n", " fieldOneDescription fieldThreeDescription fieldTwoDescription \\\n", "0 FirstName CountryISO3 LastName \n", "\n", " name seasonId type \n", "0 FIA World Rally Championship for Drivers 1 Person " ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "championship = json_normalize(championship_json).drop(['championshipEntries','championshipRounds'], axis=1)\n", "championship.head()" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{6: {'championshipId': 6,\n", " 'fieldFiveDescription': 'TyreManufacturer',\n", " 'fieldFourDescription': 'Manufacturer',\n", " 'fieldOneDescription': 'FirstName',\n", " 'fieldThreeDescription': 'CountryISO3',\n", " 'fieldTwoDescription': 'LastName',\n", " 'name': 'FIA World Rally Championship for Drivers',\n", " 'seasonId': 1,\n", " 'type': 'Person'}}" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "championships={}\n", "championship_dict = championship.to_dict()\n", "championships[champ_num] = {c:championship_dict[c][0] for c in championship_dict}\n", "championships" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'fieldFive': 'TyreManufacturer',\n", " 'fieldFour': 'Manufacturer',\n", " 'fieldOne': 'FirstName',\n", " 'fieldThree': 'CountryISO3',\n", " 'fieldTwo': 'LastName'}" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "renamer={c.replace('Description',''):championships[champ_num][c] for c in championships[champ_num] if c.startswith('field')}\n", "renamer" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
championshipEntryIdchampionshipIdentrantIdTyreManufacturerManufacturerFirstNameCountryISO3LastNamemanufacturerIdpersonIdtyreManufacturer
0316NoneMichelinfordSébastienFRAOGIER26670Michelin
1326NoneMichelintoyotaOttESTTÄNAK84524Michelin
2336NoneMichelintoyotaJari-MattiFINLATVALA84526Michelin
3346NoneMichelintoyotaEsapekkaFINLAPPI84548Michelin
4356NoneMichelincitroenKrisGBRMEEKE13550Michelin
5366NoneMichelinfordElfynGBREVANS26534Michelin
6376NoneMichelinhyundaiThierryBELNEUVILLE33522Michelin
7386NoneMichelinfordBryanFRABOUFFIER26536Michelin
8396NoneMichelincitroenCraigIRLBREEN13552Michelin
9406NoneMichelinskodaJanCZEKOPECKY77564Michelin
10456NoneMichelinhyundaiAndreasNORMIKKELSEN33538Michelin
111956NoneMichelinhyundaiHaydenNZLPADDON33764Michelin
121966NoneMichelincitroenMadsNOROSTBERG13770Michelin
131976NoneMichelinfordTeemuFINSUNINEN26566Michelin
\n", "
" ], "text/plain": [ " championshipEntryId championshipId entrantId TyreManufacturer \\\n", "0 31 6 None Michelin \n", "1 32 6 None Michelin \n", "2 33 6 None Michelin \n", "3 34 6 None Michelin \n", "4 35 6 None Michelin \n", "5 36 6 None Michelin \n", "6 37 6 None Michelin \n", "7 38 6 None Michelin \n", "8 39 6 None Michelin \n", "9 40 6 None Michelin \n", "10 45 6 None Michelin \n", "11 195 6 None Michelin \n", "12 196 6 None Michelin \n", "13 197 6 None Michelin \n", "\n", " Manufacturer FirstName CountryISO3 LastName manufacturerId personId \\\n", "0 ford Sébastien FRA OGIER 26 670 \n", "1 toyota Ott EST TÄNAK 84 524 \n", "2 toyota Jari-Matti FIN LATVALA 84 526 \n", "3 toyota Esapekka FIN LAPPI 84 548 \n", "4 citroen Kris GBR MEEKE 13 550 \n", "5 ford Elfyn GBR EVANS 26 534 \n", "6 hyundai Thierry BEL NEUVILLE 33 522 \n", "7 ford Bryan FRA BOUFFIER 26 536 \n", "8 citroen Craig IRL BREEN 13 552 \n", "9 skoda Jan CZE KOPECKY 77 564 \n", "10 hyundai Andreas NOR MIKKELSEN 33 538 \n", "11 hyundai Hayden NZL PADDON 33 764 \n", "12 citroen Mads NOR OSTBERG 13 770 \n", "13 ford Teemu FIN SUNINEN 26 566 \n", "\n", " tyreManufacturer \n", "0 Michelin \n", "1 Michelin \n", "2 Michelin \n", "3 Michelin \n", "4 Michelin \n", "5 Michelin \n", "6 Michelin \n", "7 Michelin \n", "8 Michelin \n", "9 Michelin \n", "10 Michelin \n", "11 Michelin \n", "12 Michelin \n", "13 Michelin " ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "championship_entries = json_normalize(championship_json,['championshipEntries'] )\n", "championship_entries = championship_entries.rename(columns=renamer)\n", "championship_entries = championship_entries[[c for c in championship_entries.columns if c!='']]\n", "championship_entries" ] }, { "cell_type": "code", "execution_count": 161, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
championshipIdeventIdorder
08261
18272
28283
38294
48305
58316
68327
78338
88349
983510
1083611
1183712
1283813
\n", "
" ], "text/plain": [ " championshipId eventId order\n", "0 8 26 1\n", "1 8 27 2\n", "2 8 28 3\n", "3 8 29 4\n", "4 8 30 5\n", "5 8 31 6\n", "6 8 32 7\n", "7 8 33 8\n", "8 8 34 9\n", "9 8 35 10\n", "10 8 36 11\n", "11 8 37 12\n", "12 8 38 13" ] }, "execution_count": 161, "metadata": {}, "output_type": "execute_result" } ], "source": [ "championship_rounds = json_normalize(championship_json,['championshipRounds'] ).drop('event', axis=1)\n", "championship_rounds" ] }, { "cell_type": "code", "execution_count": 162, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
categoriescountry.countryIdcountry.iso2country.iso3country.namecountryIdeventIdfinishDatelocationmodenameorganiserUrlslugstartDatesurfacestimeZoneIdtimeZoneNametimeZoneOffsettrackingEventId
0None147MCMCOMonaco147262018-01-28Monte CarloRallyRallye Monte-Carlohttps://sas.blob.core.windows.net/cdn/EventSma...rallye-monte-carlo-20182018-01-25W. Europe Standard Time(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Sto...602586
1None215SESWESweden215272018-02-18SwedenRallyRally Swedenrally-sweden-20182018-02-15W. Europe Standard Time(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Sto...602587
2None144MXMEXMexico144282018-03-11LeonRallyRally Guanajuato Méxicorally-guanajuato-mexico-20182018-03-08Central Standard Time (Mexico)(UTC-06:00) Guadalajara, Mexico City, Monterrey-3602589
3None76FRFRAFrance76292018-04-08BastiaRallyTour de Corsetour-de-corse-20182018-04-05Jordan Standard Time(UTC+02:00) Amman1202590
4None11ARARGArgentina11302018-04-29Villa Carlos PazRallyYPF Rally Argentinaypf-rally-argentina-20182018-04-26Argentina Standard Time(UTC-03:00) City of Buenos Aires-1802591
\n", "
" ], "text/plain": [ " categories country.countryId country.iso2 country.iso3 country.name \\\n", "0 None 147 MC MCO Monaco \n", "1 None 215 SE SWE Sweden \n", "2 None 144 MX MEX Mexico \n", "3 None 76 FR FRA France \n", "4 None 11 AR ARG Argentina \n", "\n", " countryId eventId finishDate location mode \\\n", "0 147 26 2018-01-28 Monte Carlo Rally \n", "1 215 27 2018-02-18 Sweden Rally \n", "2 144 28 2018-03-11 Leon Rally \n", "3 76 29 2018-04-08 Bastia Rally \n", "4 11 30 2018-04-29 Villa Carlos Paz Rally \n", "\n", " name organiserUrl \\\n", "0 Rallye Monte-Carlo https://sas.blob.core.windows.net/cdn/EventSma... \n", "1 Rally Sweden \n", "2 Rally Guanajuato México \n", "3 Tour de Corse \n", "4 YPF Rally Argentina \n", "\n", " slug startDate surfaces \\\n", "0 rallye-monte-carlo-2018 2018-01-25 \n", "1 rally-sweden-2018 2018-02-15 \n", "2 rally-guanajuato-mexico-2018 2018-03-08 \n", "3 tour-de-corse-2018 2018-04-05 \n", "4 ypf-rally-argentina-2018 2018-04-26 \n", "\n", " timeZoneId \\\n", "0 W. Europe Standard Time \n", "1 W. Europe Standard Time \n", "2 Central Standard Time (Mexico) \n", "3 Jordan Standard Time \n", "4 Argentina Standard Time \n", "\n", " timeZoneName timeZoneOffset \\\n", "0 (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Sto... 60 \n", "1 (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Sto... 60 \n", "2 (UTC-06:00) Guadalajara, Mexico City, Monterrey -360 \n", "3 (UTC+02:00) Amman 120 \n", "4 (UTC-03:00) City of Buenos Aires -180 \n", "\n", " trackingEventId \n", "0 2586 \n", "1 2587 \n", "2 2589 \n", "3 2590 \n", "4 2591 " ] }, "execution_count": 162, "metadata": {}, "output_type": "execute_result" } ], "source": [ "_events_json = json_normalize(championship_json,['championshipRounds' ])['event']\n", "championship_events = json_normalize(_events_json)\n", "championship_events.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Championship Results" ] }, { "cell_type": "code", "execution_count": 166, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
championshipEntryIdchampionshipIddroppedeventIdpointsBreakdownpositionpublishedStatusstatustotalPoints
0316False2625+11PublishedFinished26
1326False2618+02PublishedFinished18
2336False2615+23PublishedFinished17
3346False266+07PublishedFinished6
4356False2612+54PublishedFinished17
\n", "
" ], "text/plain": [ " championshipEntryId championshipId dropped eventId pointsBreakdown \\\n", "0 31 6 False 26 25+1 \n", "1 32 6 False 26 18+0 \n", "2 33 6 False 26 15+2 \n", "3 34 6 False 26 6+0 \n", "4 35 6 False 26 12+5 \n", "\n", " position publishedStatus status totalPoints \n", "0 1 Published Finished 26 \n", "1 2 Published Finished 18 \n", "2 3 Published Finished 17 \n", "3 7 Published Finished 6 \n", "4 4 Published Finished 17 " ] }, "execution_count": 166, "metadata": {}, "output_type": "execute_result" } ], "source": [ "championship_results_json=requests.get( url_base.format(stub=championship_results_stub.format(**meta2) ) ).json()\n", "championship_results = json_normalize(championship_results_json)\n", "championship_results.head()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 2 }