简体   繁体   中英

Web scraping with python/BeautifulSoup - Response 403 (minimal working example)

I am trying to learn web scraping with Python. I am trying to write a script to read the SNCF (French rail.network) website and return the lowest price on a given route on a given day after submitting a form. But I have fallen at the first hurdle. I have the following:

from bs4 import BeautifulSoup
from requests_html import HTMLSession
from urllib.parse import urljoin

session = HTMLSession()
#url = "http://sncf-connect.com"
url = "https://www.sncf-connect.com/app/home/search"

res = session.get(url)

res gives <Response [403]>

res.html.html gives:

res.html.html gives '<html><head><title>sncf-connect.com</title><style>#cmsg{animation: A 1.5s;}@keyframes A{0%{opacity:0;}99%{opacity:0;}100%{opacity:1;}}</style></head><body style="margin:0"><p id="cmsg">Please enable JS and disable any ad blocker</p><script data-cfasync="false">var dd={\'cid\':\'AHrlqAAAAAMAM3xGlPY0p-gAW6XdHw==\',\'hsh\':\'746B7C2640FFCBD6D2BEC599D9FB5F\',\'t\':\'fe\',\'s\':36834,\'e\':\'bdb536cbcc367046d999ed157f25dabb9c0736edcf90e782144a0c6d36e69e3d\',\'host\':\'geo.captcha-delivery.com\'}</script><script data-cfasync="false" src="https://ct.captcha-delivery.com/c.js"></script></body></html>\n'

I have searched online (including StackOverflow) and in similar examples I found the solution often seemed to be setting something called the User-Agent. But I have searched for this in the Chrome developer tools on the page and can't find it in my version of Chrome.

Any help or advice is much appreciated. Maybe it's impossible.

The website you are trying to scrape, will need your input to begin with. After providing initial info, their server side will make a post request to their itineraries file. It will fail because it it needs additional information (Voyageur, Ajouter etc), and it will wait until you press "Voir les prix", to receive the data from their API on their server to retrieve the pricing details.

This POST request, as shown below, will need changes in the request.json file to get the desired destination and departure. In addition, as their API might block multiple requests or change their cookies over time, you might need to change their datadome cookie and also take into account the x-bff-key header, and make sure you use a proper random sleeping delay in between requests.

import requests

cookies = {
    'datadome': 'svyNWzHgYq65uh8OXmUCRlKhBl.J34OCKJr83~87bnLPatGtWA~3PDDc8bVsDolIR4MohpgWW12trhyW_O2.q2KWZOJnWCsob~1tpI1oe.F.WCy.8kzVWaEVKhWS5zX'
}

headers = {
    'User-Agent': 'Mozilla/6.0 (X14; Linux x43_32; rv:108.0) Gecko/20100105 Firefox/108.0',
    'x-bff-key': 'ah1MPO-izehIHD-QZZ9y88n-kku876',
    'x-client-channel': 'web',
    'x-client-app-id': 'front-web',
    'x-api-env': 'production',
    'x-market-locale': 'fr_FR',
    'x-con-v': '91,210,google,c:facebook-yVzxAR44,c:snapinc-yhYnJZfT,c:tiktok-iJYQeF9m,284,c:omniture-adobe-analytics,281,27,c:contentsq-dd6Ffweb,c:microsoft,c:pinterest-gtgUFHnf,c:batch-LgBh7Kz7,c:sncfconne-4ra8mePH,c:webloyalty-DKjexkp4',
    'x-con-s': 'CPgOE0APgOE0AAHABBENCiCsAP_AAACAAAAAIDgEiCLMAWJiQWBoAOtAAQFYwAAiIEAABAAAAwABgAJAACQAkmAAIAFABCAKAAAAICJAAQAkAADAAEAAAAAAACAAAAAIAAAABiAAAAAAAAAAAAAAAQAAAAAAgAAAAAAAgAAAAAIAAEAAAQAAJAAAAAgkAADBAAAAwAAAAAAYAAAAACgcBAUAAQAAsADIAHAAPgAxAByADwAIgATAAuABiAI4AVcAuoCPQF5gMsAawA4AAgdABgACCQBCADAAEEgCkAGAAIJABoAMAAQSAFQAYAAgkAIgAwABBIAJABgACCQAyADAAEEgAAAA.f_gAABAAAAAA',
    'x-con-id': 'f3398fa776cd4cc38ef5daa1081d36be',
    'x-con-ex': 'fbae3dd8df6cb5249799ab118f987f121c8',
    'x-nav-current-path': '/app/home/shop/results/outward',
    'x-visitor-type': '0',
    'X-INSTANA-T': '90459f05f534d1b',
    'X-INSTANA-S': '90459f05f534d1b',
    'X-INSTANA-L': '1,correlationType=web;correlationId=90459f05f534d1b',
    'Origin': 'https://www.sncf-connect.com',
    'DNT': '1',
    'Connection': 'keep-alive',
    'Referer': 'https://www.sncf-connect.com/app/home/shop/results/outward',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-origin',
}

json_data = {
    'schedule': {
        'outward': {
            'date': '2022-10-03T05:00:00+02:00',
            'arrivalAt': False,
        },
    },
    'mainJourney': {
        'origin': {
            'label': 'Gare de Paris Montparnasse (Paris)',
            'id': 'RESARAIL_STA_FRPMO',
            'geolocation': False,
        },
        'destination': {
            'id': 'RESARAIL_STA_FRXSB',
            'label': 'Saint-Malo',
            'geolocation': False,
            'isEditable': True,
        },
    },
    'passengers': [
        {
            'id': 'fb831480-cde1-4c74-8361-5efc3344bf19',
            'discountCards': [],
            'typology': 'ADULT',
            'displayName': '30 - 59 ans',
            'withoutSeatAssignment': False,
        },
    ],
    'pets': [],
    'itineraryId': '64c17b9e-4880-435d-a329-a5149fbbdbad',
    'forceDisplayResults': True,
    'trainExpected': True,
    'wishBike': False,
    'strictMode': False,
    'directJourney': False,
    'metadataY': {
        'decisionAction': 'ORIGIN',
    },
}

response = requests.post('https://www.sncf-connect.com/bff/api/v1/itineraries', cookies=cookies, headers=headers, json=json_data)

This will return the data from their API in.json format:

{'longDistance': {'proposals': {'bestPrices': [{'label': 'Dim 02', 'priceLabel': '60,20 €', 'bestPriceDateTime': '2022-10-02T23:59:00', 'departureDay': False}, {'label': 'Lun 03', 'priceLabel': '37 €', 'bestPriceDateTime': '2022-10-03T15:24:00', 'departureDay': True}, {'label': 'Mar 04', 'priceLabel': '37 €', 'bestPriceDateTime': '2022-10-04T15:24:00', 'departureDay': False}, {'label': 'Mer 05', 'priceLabel': '34 €', 'bestPriceDateTime': '2022-10-05T15:24:00', 'departureDay': False}, {'label': 'Jeu 06', 'priceLabel': '43 €', 'bestPriceDateTime': '2022-10-06T07:06:00', 'departureDay': False}, {'label': 'Ven 07', 'priceLabel': '61,70 €', 'bestPriceDateTime': '2022-10-07T06:59:00', 'departureDay': False}, {'label': 'Sam 08', 'priceLabel': '37 €', 'bestPriceDateTime': '2022-10-08T15:26:00', 'departureDay': False}], 'proposals': [{'id': '467186c2-58bd-465a-8eeb-31c4ed5ba711, be22545c-5c07-44bb-b6aa-064a6a8ad06d', 'travelId': '2022-10-03T06:59_8601, 854315', 'departure': {'originStationLabel': 'Paris Montparnasse 1 Et 2', 'timeLabel': '06:59', 'dateLabel': 'Aller : Lun. 3\xa0oct.', 'displayDisabilityAssistance': False}, 'arrival': {'destinationStationLabel': 'St Malo', 'timeLabel': '09:30', 'dateLabel': 'Lun. 3\xa0oct.', 'displayDisabilityAssistance': False}, 'durationLabel': '2h31', 'segmentsIcons': [], 'transporterDescription': '1 correspondance', 'transporterSemanticDescription': '1 correspondance', 'bestPriceLabelPrefix': 'dès', 'bestPriceLabel': '53,70 €', 'passengersCount': 1, 'onBoardServices': [], 'firstComfortClassOffers': {'title': '1re classe', 'offers': [{'id': '3dd37989-84db-4de8-bd20-06c088272ddd', 'header': {'title': '1re classe', 'accessibilityTitle': '1re classe', 'subtitle': 'Premiere', 'type': 'FIRST'}, 'type': 'NORMAL', 'comfortClass': {'code': 'FIRST', 'label': '1re classe', 'accessibilityLabel': '1re classe'}, 'priceLabel': '71,10 €', 'title': 'Modifiable sous conditions', 'travelersFares': [{'id': '3dd37989-84db-4de8-bd20-06c088272ddd_55084e04-d096-4223-82e3-2ba80f935597_4b0267f2-98b1-47b3-b466-9ffff36e53df', 'travelerDescription': '30 - 59 ans', 'subtitles': ['PREMIERE'], 'priceLabel': '71,10 €', 'segmentFares': [{'transporterName': 'TGV INOUI', 'transporterSemanticName': 'TGV INOUI', 'transporterType': 'TRAIN', 'transporterDescription': '8601', 'comfort': '1re', 'fareName': 'PREMIERE', 'fareConditions': 'Billet échangeable (ajustement au tarif en vigueur) et remboursable uniquement avant départ : 15 € de frais dès 2 jours avant départ. Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. ', 'fareSemanticConditions': 'Billet échangeable (ajustement au tarif en vigueur) et remboursable uniquement avant départ : 15 € de frais dès 2 jours avant départ. Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. '}, {'transporterName': 'TER', 'transporterSemanticName': 'T E R', 'transporterType': 'TRAIN', 'transporterDescription': '854315', 'comfort': '1re', 'fareName': 'PREMIERE', 'fareConditions': 'Billet échangeable (ajustement au tarif en vigueur) et remboursable uniquement avant départ : 50% du prix le jour du départ (max 12 €). Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. ', 'fareSemanticConditions': 'Billet échangeable (ajustement au tarif en vigueur) et remboursable uniquement avant départ : 50% du prix le jour du départ (max 12 €). Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. '}], 'travelerIcon': 'TRAVELER'}], 'segmentServices': [], 'segmentPlacements': {'segments': [{'segmentInfo': {'segmentId': '467186c2-58bd-465a-8eeb-31c4ed5ba711', 'originLabel': 'Paris Montparnasse 1 Et 2', 'destinationLabel': 'Rennes', 'transporterLogo': 'tgv_inoui', 'transporterDescription': 'TGV INOUI 8601 - 1re classe', 'accessibilityTransporterDescription': 'TGV INOUI 8601 - 1re classe', 'comfort': '1re'}, 'meas': [], 'defaultPlacement': 'FRONT_SEAT_MAP', 'preferencesPlacementMode': {'placementModeType': 'FRONT_PREFERENCES', 'placementModeLabel': 'Selon vos préférences', 'deckChoices': {'label': 'Salle', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': [{'code': 'HAUT', 'label': 'Salle haute', 'icon': {'iconGroup': 'Placement', 'iconName': 'high_area'}, 'disabled': False}, {'code': 'BAS', 'label': 'Salle basse', 'icon': {'iconGroup': 'Placement', 'iconName': 'low_area'}, 'disabled': False}]}, 'seatChoices': {'label': 'Siège', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': [{'code': 'FENETRE', 'label': 'Fenêtre', 'icon': {'iconGroup': 'Placement', 'iconName': 'window_side'}, 'disabled': False}, {'code': 'COULOIR', 'label': 'Couloir', 'icon': {'iconGroup': 'Placement', 'iconName': 'aisle_side'}, 'disabled': False}, {'code': 'ISOLE', 'label': 'Isolé', 'icon': {'iconGroup': 'Placement', 'iconName': 'solo'}, 'disabled': False}, {'code': 'DUO_COTE_A_COTE', 'label': 'Duo côte-à-côte', 'icon': {'iconGroup': 'Placement', 'iconName': 'side_by_side'}, 'disabled': False}, {'code': 'DUO_VIS_A_VIS', 'label': 'Duo vis-à-vis', 'icon': {'iconGroup': 'Placement', 'iconName': 'club_duo'}, 'disabled': False}, {'code': 'SOLO', 'label': 'Solo', 'icon': {'iconGroup': 'Placement', 'iconName': 'solo'}, 'disabled': False}]}, 'berthChoices': {'travelerTitleLabel': 'Sélectionnez un voyageur', 'travelersLabels': ['Voyageur 1'], 'placementChoices': {'label': 'Sélectionner une couchette', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': []}}, 'comfortSpaces': [], 'facingForwardLabel': 'Dans le sens de la marche'}, 'closeToPlacementMode': {'placementModeType': 'FRONT_CLOSE_TO', 'placementModeLabel': "À côté d'un proche", 'coachNumberPlaceholder': 'N° de voiture', 'seatNumberPlaceholder': 'N° de place'}, 'seatMapPlacementMode': {'placementModeType': 'FRONT_SEAT_MAP', 'placementModeLabel': 'Choisir sur le plan du train', 'seatMapButtonLabel': 'Choisir votre place', 'seatMapModifyLabel': 'Modifier votre placement', 'placementOptions': []}}, {'segmentInfo': {'segmentId': 'be22545c-5c07-44bb-b6aa-064a6a8ad06d', 'originLabel': 'Rennes', 'destinationLabel': 'St Malo', 'transporterLogo': 'ter', 'transporterDescription': 'TER 854315 - 1re classe', 'accessibilityTransporterDescription': 'TER 854315 - 1re classe', 'comfort': '1re'}, 'meas': [], 'defaultPlacement': 'FRONT_NO_PLACEMENT', 'noPlacementMode': {'placementModeType': 'FRONT_NO_PLACEMENT', 'placementModeLabel': 'Placement libre'}}], 'submitWarningLabel': 'Vos préférences seront prises en compte en fonction des disponibilités.', 'submitButtonLabel': 'Valider ce placement', 'isOneOfComfortSpacesMandatory': False}, 'messages': [], 'services': {'title': 'Nos services en 1re', 'services': [], 'accessibilityTitle': 'Nos services en 1re'}, 'transportersFareConditions': [], 'defaultButtonLabel': 'Choisir cet aller à', 'inwardButtonLabel': 'Choisir ce retour à'}, {'id': '5b02fc36-9f7c-4b08-9f5c-5730fb4b0c94', 'header': {'title': 'Business Premiere', 'accessibilityTitle': 'Business Premiere', 'type': 'PRO'}, 'type': 'NORMAL', 'comfortClass': {'code': 'FIRST', 'label': 'Business Premiere', 'accessibilityLabel': 'Business Premiere'}, 'priceLabel': '150,10 €', 'title': 'Modifiable sans frais', 'travelersFares': [{'id': '5b02fc36-9f7c-4b08-9f5c-5730fb4b0c94_4a1b0f7c-c0b2-4092-a4ed-f5ddb5d590e7_e34f5bee-5616-4921-8878-1a3088d3d9ee', 'travelerDescription': '30 - 59 ans', 'subtitles': ['BUSINESS PREMIERE'], 'priceLabel': '150,10 €', 'segmentFares': [{'transporterName': 'TGV INOUI', 'transporterSemanticName': 'TGV INOUI', 'transporterType': 'TRAIN', 'transporterDescription': '8601', 'comfort': '1re', 'fareName': 'BUSINESS PREMIERE', 'fareConditions': "Echange et remboursement sans frais jusqu'à 30 min après départ. Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. Si emprunt d’un autre train, échange obligatoire. ", 'fareSemanticConditions': "Echange et remboursement sans frais jusqu'à 30 min après départ. Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. Si emprunt d’un autre train, échange obligatoire. "}, {'transporterName': 'TER', 'transporterSemanticName': 'T E R', 'transporterType': 'TRAIN', 'transporterDescription': '854315', 'comfort': '1re', 'fareName': 'BUSINESS PREMIERE', 'fareConditions': "Echange et remboursement sans frais jusqu'à 30 min après départ. Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. Si emprunt d’un autre train, échange obligatoire. ", 'fareSemanticConditions': "Echange et remboursement sans frais jusqu'à 30 min après départ. Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. Si emprunt d’un autre train, échange obligatoire. "}], 'travelerIcon': 'TRAVELER'}], 'segmentServices': [], 'segmentPlacements': {'segments': [{'segmentInfo': {'segmentId': '467186c2-58bd-465a-8eeb-31c4ed5ba711', 'originLabel': 'Paris Montparnasse 1 Et 2', 'destinationLabel': 'Rennes', 'transporterLogo': 'tgv_inoui', 'transporterDescription': 'TGV INOUI 8601 - 1re classe', 'accessibilityTransporterDescription': 'TGV INOUI 8601 - 1re classe', 'comfort': '1re'}, 'meas': [], 'defaultPlacement': 'FRONT_SEAT_MAP', 'preferencesPlacementMode': {'placementModeType': 'FRONT_PREFERENCES', 'placementModeLabel': 'Selon vos préférences', 'deckChoices': {'label': 'Salle', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': [{'code': 'HAUT', 'label': 'Salle haute', 'icon': {'iconGroup': 'Placement', 'iconName': 'high_area'}, 'disabled': False}, {'code': 'BAS', 'label': 'Salle basse', 'icon': {'iconGroup': 'Placement', 'iconName': 'low_area'}, 'disabled': False}]}, 'seatChoices': {'label': 'Siège', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': [{'code': 'FENETRE', 'label': 'Fenêtre', 'icon': {'iconGroup': 'Placement', 'iconName': 'window_side'}, 'disabled': False}, {'code': 'COULOIR', 'label': 'Couloir', 'icon': {'iconGroup': 'Placement', 'iconName': 'aisle_side'}, 'disabled': False}, {'code': 'ISOLE', 'label': 'Isolé', 'icon': {'iconGroup': 'Placement', 'iconName': 'solo'}, 'disabled': False}, {'code': 'DUO_COTE_A_COTE', 'label': 'Duo côte-à-côte', 'icon': {'iconGroup': 'Placement', 'iconName': 'side_by_side'}, 'disabled': False}, {'code': 'DUO_VIS_A_VIS', 'label': 'Duo vis-à-vis', 'icon': {'iconGroup': 'Placement', 'iconName': 'club_duo'}, 'disabled': False}, {'code': 'SOLO', 'label': 'Solo', 'icon': {'iconGroup': 'Placement', 'iconName': 'solo'}, 'disabled': False}]}, 'berthChoices': {'travelerTitleLabel': 'Sélectionnez un voyageur', 'travelersLabels': ['Voyageur 1'], 'placementChoices': {'label': 'Sélectionner une couchette', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': []}}, 'comfortSpaces': [], 'facingForwardLabel': 'Dans le sens de la marche'}, 'closeToPlacementMode': {'placementModeType': 'FRONT_CLOSE_TO', 'placementModeLabel': "À côté d'un proche", 'coachNumberPlaceholder': 'N° de voiture', 'seatNumberPlaceholder': 'N° de place'}, 'seatMapPlacementMode': {'placementModeType': 'FRONT_SEAT_MAP', 'placementModeLabel': 'Choisir sur le plan du train', 'seatMapButtonLabel': 'Choisir votre place', 'seatMapModifyLabel': 'Modifier votre placement', 'placementOptions': []}}, {'segmentInfo': {'segmentId': 'be22545c-5c07-44bb-b6aa-064a6a8ad06d', 'originLabel': 'Rennes', 'destinationLabel': 'St Malo', 'transporterLogo': 'ter', 'transporterDescription': 'TER 854315 - 1re classe', 'accessibilityTransporterDescription': 'TER 854315 - 1re classe', 'comfort': '1re'}, 'meas': [], 'defaultPlacement': 'FRONT_NO_PLACEMENT', 'noPlacementMode': {'placementModeType': 'FRONT_NO_PLACEMENT', 'placementModeLabel': 'Placement libre'}}], 'submitWarningLabel': 'Vos préférences seront prises en compte en fonction des disponibilités.', 'submitButtonLabel': 'Valider ce placement', 'isOneOfComfortSpacesMandatory': False}, 'messages': [], 'services': {'title': 'Nos services Premium', 'services': [], 'accessibilityTitle': 'Nos services Premium'}, 'transportersFareConditions': [], 'defaultButtonLabel': 'Choisir cet aller à', 'inwardButtonLabel': 'Choisir ce retour à'}], 'bestPriceLabelPrefix': 'dès', 'bestPriceLabel': '71,10 €'}, 'secondComfortClassOffers': {'title': '2de classe', 'accessibilityTitle': 'Seconde classe', 'offers': [{'id': '0fa8bf09-c819-461b-b106-71276134beed', 'header': {'title': '2de classe', 'accessibilityTitle': 'Seconde classe', 'subtitle': 'Seconde', 'type': 'SECOND'}, 'type': 'NORMAL', 'comfortClass': {'code': 'SECOND', 'label': '2de classe', 'accessibilityLabel': 'Seconde classe'}, 'priceLabel': '53,70 €', 'title': 'Modifiable sous conditions', 'travelersFares': [{'id': '0fa8bf09-c819-461b-b106-71276134beed_ef5a8a70-c86a-4a47-9ac4-f26f9fdc30b2_fabf46d0-da4a-42dd-b9b6-3c54625b665e', 'travelerDescription': '30 - 59 ans', 'subtitles': ['SECONDE'], 'priceLabel': '53,70 €', 'segmentFares': [{'transporterName': 'TGV INOUI', 'transporterSemanticName': 'TGV INOUI', 'transporterType': 'TRAIN', 'transporterDescription': '8601', 'comfort': '2de', 'fareName': 'SECONDE', 'fareConditions': 'Billet échangeable (ajustement au tarif en vigueur) et remboursable uniquement avant départ : 15 € de frais dès 2 jours avant départ. Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. ', 'fareSemanticConditions': 'Billet échangeable (ajustement au tarif en vigueur) et remboursable uniquement avant départ : 15 € de frais dès 2 jours avant départ. Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. '}, {'transporterName': 'TER', 'transporterSemanticName': 'T E R', 'transporterType': 'TRAIN', 'transporterDescription': '854315', 'comfort': '2de', 'fareName': 'SECONDE', 'fareConditions': 'Billet échangeable (ajustement au tarif en vigueur) et remboursable uniquement avant départ : 50% du prix le jour du départ (max 12 €). Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. ', 'fareSemanticConditions': 'Billet échangeable (ajustement au tarif en vigueur) et remboursable uniquement avant départ : 50% du prix le jour du départ (max 12 €). Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. '}], 'travelerIcon': 'TRAVELER'}], 'segmentServices': [], 'segmentPlacements': {'segments': [{'segmentInfo': {'segmentId': '467186c2-58bd-465a-8eeb-31c4ed5ba711', 'originLabel': 'Paris Montparnasse 1 Et 2', 'destinationLabel': 'Rennes', 'transporterLogo': 'tgv_inoui', 'transporterDescription': 'TGV INOUI 8601 - 2de classe', 'accessibilityTransporterDescription': 'TGV INOUI 8601 - Seconde classe', 'comfort': '2de'}, 'meas': [], 'defaultPlacement': 'FRONT_PREFERENCES', 'preferencesPlacementMode': {'placementModeType': 'FRONT_PREFERENCES', 'placementModeLabel': 'Selon vos préférences', 'deckChoices': {'label': 'Salle', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': [{'code': 'HAUT', 'label': 'Salle haute', 'icon': {'iconGroup': 'Placement', 'iconName': 'high_area'}, 'disabled': False}, {'code': 'BAS', 'label': 'Salle basse', 'icon': {'iconGroup': 'Placement', 'iconName': 'low_area'}, 'disabled': False}]}, 'seatChoices': {'label': 'Siège', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': [{'code': 'FENETRE', 'label': 'Fenêtre', 'icon': {'iconGroup': 'Placement', 'iconName': 'window_side'}, 'disabled': False}, {'code': 'COULOIR', 'label': 'Couloir', 'icon': {'iconGroup': 'Placement', 'iconName': 'aisle_side'}, 'disabled': False}]}, 'berthChoices': {'travelerTitleLabel': 'Sélectionnez un voyageur', 'travelersLabels': ['Voyageur 1'], 'placementChoices': {'label': 'Sélectionner une couchette', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': []}}, 'comfortSpaces': [], 'facingForwardLabel': 'Dans le sens de la marche'}, 'closeToPlacementMode': {'placementModeType': 'FRONT_CLOSE_TO', 'placementModeLabel': "À côté d'un proche", 'coachNumberPlaceholder': 'N° de voiture', 'seatNumberPlaceholder': 'N° de place'}}, {'segmentInfo': {'segmentId': 'be22545c-5c07-44bb-b6aa-064a6a8ad06d', 'originLabel': 'Rennes', 'destinationLabel': 'St Malo', 'transporterLogo': 'ter', 'transporterDescription': 'TER 854315 - 2de classe', 'accessibilityTransporterDescription': 'TER 854315 - Seconde classe', 'comfort': '2de'}, 'meas': [], 'defaultPlacement': 'FRONT_NO_PLACEMENT', 'noPlacementMode': {'placementModeType': 'FRONT_NO_PLACEMENT', 'placementModeLabel': 'Placement libre'}}], 'submitWarningLabel': 'Vos préférences seront prises en compte en fonction des disponibilités.', 'submitButtonLabel': 'Valider ce placement', 'isOneOfComfortSpacesMandatory': False}, 'messages': [], 'services': {'title': 'Nos services en 2de', 'services': [], 'accessibilityTitle': 'Nos services en seconde'}, 'transportersFareConditions': [], 'defaultButtonLabel': 'Choisir cet aller à', 'inwardButtonLabel': 'Choisir ce retour à'}, {'id': '8cb02037-ca3f-4280-ba73-0a82593c6030', 'header': {'title': '2de classe', 'accessibilityTitle': 'Seconde classe', 'type': 'SECOND'}, 'type': 'NORMAL', 'comfortClass': {'code': 'SECOND', 'label': '2de classe', 'accessibilityLabel': 'Seconde classe'}, 'priceLabel': '58 €', 'title': 'Modifiable sous conditions', 'travelersFares': [{'id': '8cb02037-ca3f-4280-ba73-0a82593c6030_9ec5ed7b-c3d0-4b51-bbfb-dea87aa3dca0_82b2c2cb-3fb8-4bd7-9811-5e2d10c2e75c', 'travelerDescription': '30 - 59 ans', 'subtitles': ['SECONDE', 'Tarif normal'], 'priceLabel': '58 €', 'segmentFares': [{'transporterName': 'TGV INOUI', 'transporterSemanticName': 'TGV INOUI', 'transporterType': 'TRAIN', 'transporterDescription': '8601', 'comfort': '2de', 'fareName': 'SECONDE', 'fareConditions': 'Billet échangeable (ajustement au tarif en vigueur) et remboursable uniquement avant départ : 15 € de frais dès 2 jours avant départ. Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. ', 'fareSemanticConditions': 'Billet échangeable (ajustement au tarif en vigueur) et remboursable uniquement avant départ : 15 € de frais dès 2 jours avant départ. Dès 30 min avant départ, billet échangeable 2 fois max (même jour, même trajet) et non remboursable après 1 échange. '}, {'transporterName': 'TER', 'transporterSemanticName': 'T E R', 'transporterType': 'TRAIN', 'transporterDescription': '854315', 'comfort': '2de', 'fareName': 'Tarif normal', 'fareConditions': 'Avec réservation : échange et remboursement sans frais avant départ, puis 50% de retenue. Sans réservation : échange sans frais pour un billet avec réservation, une réduction moins importante ou surclassement. Dans tous les autres cas\xa0: retenue de 10% pendant la validité. Si e-billet : utilisable sur le train à la date indiquée, échange et remboursement sans frais avant départ. ', 'fareSemanticConditions': 'Avec réservation : échange et remboursement sans frais avant départ, puis 50% de retenue. Sans réservation : échange sans frais pour un billet avec réservation, une réduction moins importante ou surclassement. Dans tous les autres cas\xa0: retenue de 10% pendant la validité. Si e-billet : utilisable sur le train à la date indiquée, échange et remboursement sans frais avant départ. '}], 'travelerIcon': 'TRAVELER'}], 'segmentServices': [], 'segmentPlacements': {'segments': [{'segmentInfo': {'segmentId': '467186c2-58bd-465a-8eeb-31c4ed5ba711', 'originLabel': 'Paris Montparnasse 1 Et 2', 'destinationLabel': 'Rennes', 'transporterLogo': 'tgv_inoui', 'transporterDescription': 'TGV INOUI 8601 - 2de classe', 'accessibilityTransporterDescription': 'TGV INOUI 8601 - Seconde classe', 'comfort': '2de'}, 'meas': [], 'defaultPlacement': 'FRONT_PREFERENCES', 'preferencesPlacementMode': {'placementModeType': 'FRONT_PREFERENCES', 'placementModeLabel': 'Selon vos préférences', 'deckChoices': {'label': 'Salle', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': [{'code': 'HAUT', 'label': 'Salle haute', 'icon': {'iconGroup': 'Placement', 'iconName': 'high_area'}, 'disabled': False}, {'code': 'BAS', 'label': 'Salle basse', 'icon': {'iconGroup': 'Placement', 'iconName': 'low_area'}, 'disabled': False}]}, 'seatChoices': {'label': 'Siège', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': [{'code': 'FENETRE', 'label': 'Fenêtre', 'icon': {'iconGroup': 'Placement', 'iconName': 'window_side'}, 'disabled': False}, {'code': 'COULOIR', 'label': 'Couloir', 'icon': {'iconGroup': 'Placement', 'iconName': 'aisle_side'}, 'disabled': False}]}, 'berthChoices': {'travelerTitleLabel': 'Sélectionnez un voyageur', 'travelersLabels': ['Voyageur 1'], 'placementChoices': {'label': 'Sélectionner une couchette', 'any': {'code': 'ANY', 'label': 'Indifférent', 'disabled': False}, 'choices': []}}, 'comfortSpaces': [], 'facingForwardLabel': 'Dans le sens de la marche'}, 'closeToPlacementMode': {'placementModeType': 'FRONT_CLOSE_TO', 'placementModeLabel': "À côté d'un proche", 'coachNumberPlaceholder': 'N° de voiture', 'seatNumberPlaceholder': 'N° de place'}}, {'segmentInfo': {'segmentId': 'be22545c-5c07-44bb-b6aa-064a6a8ad06d', 'originLabel': 'Rennes', 'destinationLabel': 'St Malo', 'transporterLogo': 'ter', 'transporterDescription': 'TER 854315 - 2de classe', 'accessibilityTransporterDescription': 'TER 854315 - Seconde classe', 'comfort': '2de'}, 'meas': [], 'defaultPlacement': 'FRONT_NO_PLACEMENT', 'noPlacementMode': {'placementModeType': 'FRONT_NO_PLACEMENT', 'placementModeLabel': 'Placement libre'}}]```

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM