Сообщение запроса GraphQL с запросом Python

Я пытался отправить запрос с помощью Python, чтобы очистить некоторые данные json с сайта. У меня нет опыта работы с GraphQL, но я думаю, что этот сайт построен на нем. Так или иначе, проблема в том, что даже если я запрашиваю его с помощью метода POST, он продолжает возвращать мне GRAPHQL_PARSE_FAILED (я опубликую результат ниже). Я предполагаю, что это потому, что в моем запросе есть «стрелка вниз с углом влево». Поскольку в сообщении говорится, что он не может проанализировать '\ u21B5'.

Вот код.

self.API_URL = 'https://pcmap-api.place.naver.com/graphql'

def get_location_info(self, query, start):
    header = {
        'authority': 'pcmap-api.place.naver.com',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36'
    }

    query = """
    {
        "query getRestaurants($input: RestaurantsInput, $isNmap: Boolean!, $isBounds: Boolean!) {↵  restaurants(input: $input) {↵    total↵    items {↵      ...RestaurantItemFields↵      easyOrder {↵        easyOrderId↵        easyOrderCid↵        businessHours {↵          weekday {↵            start↵            end↵            __typename↵          }↵          weekend {↵            start↵            end↵            __typename↵          }↵          __typename↵        }↵        __typename↵      }↵      baemin {↵        businessHours {↵          deliveryTime {↵            start↵            end↵            __typename↵          }↵          closeDate {↵            start↵            end↵            __typename↵          }↵          temporaryCloseDate {↵            start↵            end↵            __typename↵          }↵          __typename↵        }↵        __typename↵      }↵      yogiyo {↵        businessHours {↵          actualDeliveryTime {↵            start↵            end↵            __typename↵          }↵          bizHours {↵            start↵            end↵            __typename↵          }↵          __typename↵        }↵        __typename↵      }↵      __typename↵    }↵    nlu {↵      ...NluFields↵      __typename↵    }↵    brand {↵      name↵      isBrand↵      type↵      menus {↵        order↵        id↵        images {↵          url↵          desc↵          __typename↵        }↵        name↵        desc↵        price↵        isRepresentative↵        detailUrl↵        orderType↵        catalogId↵        source↵        menuId↵        nutrients↵        allergies↵        __typename↵      }↵      __typename↵    }↵    optionsForMap @include(if: $isBounds) {↵      maxZoom↵      minZoom↵      includeMyLocation↵      maxIncludePoiCount↵      center↵      spotId↵      __typename↵    }↵    __typename↵  }↵}↵↵fragment RestaurantItemFields on RestaurantSummary {↵  id↵  dbType↵  name↵  businessCategory↵  category↵  description↵  hasBooking↵  hasNPay↵  x↵  y↵  distance↵  imageUrl↵  imageUrls↵  imageCount↵  phone↵  virtualPhone↵  routeUrl↵  streetPanorama {↵    id↵    pan↵    tilt↵    lat↵    lon↵    __typename↵  }↵  roadAddress↵  address↵  commonAddress↵  blogCafeReviewCount↵  bookingReviewCount↵  totalReviewCount↵  bookingReviewScore↵  bookingUrl↵  bookingBusinessId↵  talktalkUrl↵  options↵  promotionTitle↵  agencyId↵  businessHours↵  microReview↵  tags↵  priceCategory↵  broadcastInfo {↵    program↵    date↵    menu↵    __typename↵  }↵  michelinGuide {↵    year↵    star↵    comment↵    url↵    hasGrade↵    isBib↵    alternateText↵    __typename↵  }↵  broadcasts {↵    program↵    menu↵    episode↵    broadcast_date↵    __typename↵  }↵  tvcastId↵  naverBookingCategory↵  saveCount↵  uniqueBroadcasts↵  isDelivery↵  markerLabel @include(if: $isNmap) {↵    text↵    style↵    __typename↵  }↵  imageMarker @include(if: $isNmap) {↵    marker↵    markerSelected↵    __typename↵  }↵  isTableOrder↵  isPreOrder↵  isTakeOut↵  bookingDisplayName↵  bookingVisitId↵  bookingPickupId↵  popularMenuImages {↵    name↵    price↵    bookingCount↵    menuUrl↵    menuListUrl↵    imageUrl↵    isPopular↵    usePanoramaImage↵    __typename↵  }↵  visitorReviewCount↵  visitorReviewScore↵  detailCid {↵    c0↵    c1↵    c2↵    c3↵    __typename↵  }↵  streetPanorama {↵    id↵    pan↵    tilt↵    lat↵    lon↵    __typename↵  }↵  __typename↵}↵↵fragment NluFields on Nlu {↵  queryType↵  user {↵    gender↵    __typename↵  }↵  queryResult {↵    ptn0↵    ptn1↵    region↵    spot↵    tradeName↵    service↵    selectedRegion {↵      name↵      index↵      x↵      y↵      __typename↵    }↵    selectedRegionIndex↵    otherRegions {↵      name↵      index↵      __typename↵    }↵    property↵    keyword↵    queryType↵    nluQuery↵    businessType↵    cid↵    branch↵    franchise↵    titleKeyword↵    location {↵      x↵      y↵      default↵      longitude↵      latitude↵      dong↵      si↵      __typename↵    }↵    noRegionQuery↵    priority↵    showLocationBarFlag↵    themeId↵    filterBooking↵    repRegion↵    repSpot↵    dbQuery {↵      isDefault↵      name↵      type↵      getType↵      useFilter↵      hasComponents↵      __typename↵    }↵    type↵    category↵    __typename↵  }↵  __typename↵}↵"
    }
    """ 

    data = {
        'operationName': "getRestaurants",
        'query': query,
        'variables': {'input': {
            'deviceType': "pcmap",
            'display': "50",
            'isNmap': "false",
            'query': query,
            'start': start
        },
        'isBound': 'true',
        'isNmap': 'false'
        }
    }
    r = requests.post(self.API_URL, headers=header, json=data).json()

Как вы можете видеть в запросе, у него есть стрелка, которую GraphQL не может проанализировать. Я предполагаю, что мне нужно преобразовать запрос в какой-то вид, понятный GraphQL. Но это немного расстраивает, так как я просто скопировал и вставил то, что только что показало Request Payload. Я поместил запрос вне параметра данных, потому что он казался слишком запутанным.

Вот результат.

{
"errors": [
    {
        "extensions": {
            "code": "GRAPHQL_PARSE_FAILED"
        },
        "locations": [
            {
                "column": 89,
                "line": 1
            }
        ],
        "message": "Syntax Error: Cannot parse the unexpected character \"\\u21B5\".",
        "status": 500
    }
]

}

Я действительно был бы признателен, если бы вы придумали способ решить эту проблему. Спасибо!


person bbq12340    schedule 08.10.2020    source источник


Ответы (1)


Ваша переменная query должна быть без фигурных скобок И вы должны заменить все символы '↵' на '\ n':

query = "query getRestaurants($input: RestaurantsInput, $isNmap: Boolean!, $isBounds: Boolean!) {\n  restaurants(input: $input) {\n    total\n    items {\n      ...RestaurantItemFields\n      easyOrder {\n        easyOrderId\n        easyOrderCid\n        businessHours {\n          weekday {\n            start\n            end\n            __typename\n          }\n          weekend {\n            start\n            end\n            __typename\n          }\n          __typename\n        }\n        __typename\n      }\n      baemin {\n        businessHours {\n          deliveryTime {\n            start\n            end\n            __typename\n          }\n          closeDate {\n            start\n            end\n            __typename\n          }\n          temporaryCloseDate {\n            start\n            end\n            __typename\n          }\n          __typename\n        }\n        __typename\n      }\n      yogiyo {\n        businessHours {\n          actualDeliveryTime {\n            start\n            end\n            __typename\n          }\n          bizHours {\n            start\n            end\n            __typename\n          }\n          __typename\n        }\n        __typename\n      }\n      __typename\n    }\n    nlu {\n      ...NluFields\n      __typename\n    }\n    brand {\n      name\n      isBrand\n      type\n      menus {\n        order\n        id\n        images {\n          url\n          desc\n          __typename\n        }\n        name\n        desc\n        price\n        isRepresentative\n        detailUrl\n        orderType\n        catalogId\n        source\n        menuId\n        nutrients\n        allergies\n        __typename\n      }\n      __typename\n    }\n    optionsForMap @include(if: $isBounds) {\n      maxZoom\n      minZoom\n      includeMyLocation\n      maxIncludePoiCount\n      center\n      spotId\n      __typename\n    }\n    __typename\n  }\n}\n\nfragment RestaurantItemFields on RestaurantSummary {\n  id\n  dbType\n  name\n  businessCategory\n  category\n  description\n  hasBooking\n  hasNPay\n  x\n  y\n  distance\n  imageUrl\n  imageUrls\n  imageCount\n  phone\n  virtualPhone\n  routeUrl\n  streetPanorama {\n    id\n    pan\n    tilt\n    lat\n    lon\n    __typename\n  }\n  roadAddress\n  address\n  commonAddress\n  blogCafeReviewCount\n  bookingReviewCount\n  totalReviewCount\n  bookingReviewScore\n  bookingUrl\n  bookingBusinessId\n  talktalkUrl\n  options\n  promotionTitle\n  agencyId\n  businessHours\n  microReview\n  tags\n  priceCategory\n  broadcastInfo {\n    program\n    date\n    menu\n    __typename\n  }\n  michelinGuide {\n    year\n    star\n    comment\n    url\n    hasGrade\n    isBib\n    alternateText\n    __typename\n  }\n  broadcasts {\n    program\n    menu\n    episode\n    broadcast_date\n    __typename\n  }\n  tvcastId\n  naverBookingCategory\n  saveCount\n  uniqueBroadcasts\n  isDelivery\n  markerLabel @include(if: $isNmap) {\n    text\n    style\n    __typename\n  }\n  imageMarker @include(if: $isNmap) {\n    marker\n    markerSelected\n    __typename\n  }\n  isTableOrder\n  isPreOrder\n  isTakeOut\n  bookingDisplayName\n  bookingVisitId\n  bookingPickupId\n  popularMenuImages {\n    name\n    price\n    bookingCount\n    menuUrl\n    menuListUrl\n    imageUrl\n    isPopular\n    usePanoramaImage\n    __typename\n  }\n  visitorReviewCount\n  visitorReviewScore\n  detailCid {\n    c0\n    c1\n    c2\n    c3\n    __typename\n  }\n  streetPanorama {\n    id\n    pan\n    tilt\n    lat\n    lon\n    __typename\n  }\n  __typename\n}\n\nfragment NluFields on Nlu {\n  queryType\n  user {\n    gender\n    __typename\n  }\n  queryResult {\n    ptn0\n    ptn1\n    region\n    spot\n    tradeName\n    service\n    selectedRegion {\n      name\n      index\n      x\n      y\n      __typename\n    }\n    selectedRegionIndex\n    otherRegions {\n      name\n      index\n      __typename\n    }\n    property\n    keyword\n    queryType\n    nluQuery\n    businessType\n    cid\n    branch\n    franchise\n    titleKeyword\n    location {\n      x\n      y\n      default\n      longitude\n      latitude\n      dong\n      si\n      __typename\n    }\n    noRegionQuery\n    priority\n    showLocationBarFlag\n    themeId\n    filterBooking\n    repRegion\n    repSpot\n    dbQuery {\n      isDefault\n      name\n      type\n      getType\n      useFilter\n      hasComponents\n      __typename\n    }\n    type\n    category\n    __typename\n  }\n  __typename\n}\n"

Кроме того, ваши логические значения на самом деле являются строками, вам нужно определить их следующим образом:

'variables': {
  'input': {
    ...
    'isNmap': False,
    ...
  },
  'isBound': True,
  'isNmap': False
}
person GProst    schedule 08.10.2020
comment
Обновил мой ответ - person GProst; 09.10.2020
comment
Хм, он возвращает мне внутреннюю ошибку сервера. «$ IsNmap» и «$ isBounds» не были предоставлены с «Boolean!» Я не уверен, что это означает, но я действительно запутался, потому что я вставил логические значения в каждый параметр данных. Я не уверен, как работает graphql, но он звонит из множества .js, когда я мельком взглянул на Инициаторы. - person bbq12340; 09.10.2020
comment
Обновил мой ответ - person GProst; 09.10.2020
comment
Я попробовал ваши рекомендации и думаю, что мы почти закончили. Но я все еще не могу получить данные, поэтому я разместил json, который получил ниже. - person bbq12340; 10.10.2020