Ошибка 403 при выполнении HTTP-запроса с модификацией в Котлине

Я работаю над проектом Android, в котором мне нужно отправить HTTP-запрос в конечную точку поиска, используя библиотеку Retrofit в Котлине. Запрос работает нормально, когда я ввожу URL-адрес непосредственно в свой браузер, но когда я пытаюсь отправить запрос программно, я получаю ошибку 403.

Вот URL-адрес, который я пытаюсь запросить: https://apkpure.com/search?q=free+fire

А это фрагмент кода, в котором я настраиваю Retrofit и делаю вызов:

interface ApiService {
  @GET("search?q=free+fire&t = ")
  suspend fun searchResults(): Response<String>
}

val retrofit = Retrofit.Builder()
    .baseUrl("https://apkpure.com/")
    .addConverterFactory(ScalarsConverterFactory.create())
    .build()
    .create(ApiService::class.java)

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

Response Error: 403, Error Body: <!DOCTYPE html><html lang = "en-US"><head><title>Just a moment...</title><meta http-equiv = "Content-Type" content = "text/html;

Кажется, что сервер отклоняет мой программный запрос, но не тогда, когда я использую веб-браузер. Может ли это быть связано с проверкой пользовательского агента или какой-либо другой формой проверки запроса, которую выполняет сервер?

Как я могу изменить свой запрос, чтобы избежать этой ошибки и успешно получить данные, как это делает мой браузер?

Я попытался добавить пользовательский агент по моему запросу, чтобы это могло решить проблему, но этого не произошло. Вот код:

val okHttpClient = OkHttpClient.Builder()
      .addInterceptor { chain ->
        val originalRequest = chain.request()
        val requestWithUserAgent = originalRequest.newBuilder()
          .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3")
          .build()
        chain.proceed(requestWithUserAgent)
      }
      .build()

    val retrofit = Retrofit.Builder()
      .baseUrl("https://apkpure.com/")
      .client(okHttpClient)
      .addConverterFactory(ScalarsConverterFactory.create())
      .build()
      .create(ApiService::class.java)

Все равно выдает ту же ошибку...

1
0
146
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я тестировал его с помощью Postman, и он работал пару раз, возвращая тело HTML-страницы, но после 10 попыток он вернет 403 Forbidden.

Вероятно, вы вызывали его слишком много раз за короткий период времени, и впоследствии он заблокировал ваш запрос.

Это не проблема отправки слишком большого количества запросов; Я это проверил. Интересно, что когда я использую веб-версию Postman, запрос выполняется без проблем. Однако тот же запрос через библиотеку Retrofit приводит к ошибке. Это заставляет меня подозревать, что Postman может включать определенные заголовки или выполнять некоторые фоновые операции, которые позволяют ему получить правильный ответ. Есть ли способ воспроизвести это поведение в Retrofit и добиться такого же успешного ответа?

TDKMS 07.05.2024 17:36

Вы отправляете запросы на веб-сайт, который, вероятно, защищен брандмауэром (WAP), их общедоступный веб-сайт предназначен для обычных пользователей. Я думаю, что если вы хотите использовать веб-сайт в целях разработки, вам необходимо направлять запросы к их API. не на обычный сайт (если у них есть API)

Если у них есть общедоступный API, адрес должен быть примерно таким: api.apkpure.com/search где api.apkpure.com/ — базовый URL-адрес API, а search — конечная точка.

Ответ принят как подходящий

После некоторого расследования я обнаружил, что рассматриваемый веб-сайт использует JavaScript для обработки запросов. Это создавало проблемы при использовании Retrofit для сетевых операций, поскольку Retrofit не поддерживает выполнение JavaScript. Следовательно, запросы, отправленные через Retrofit, обрабатываются так, как будто JavaScript отключен, что делает его неспособным обрабатывать веб-страницы, требующие JavaScript.

Чтобы решить эту проблему, я экспериментировал с библиотекой Scrape{it}, которая успешно обрабатывала JavaScript, но вызывала значительную задержку. Альтернативное решение — использовать WebView, который позволяет выполнять JavaScript в своей среде. Включив JavaScript в WebView, вы можете вручную извлекать результаты со страницы.

Вот фрагмент для включения JavaScript в WebView:

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();

webSettings.setJavaScriptEnabled(true);

Этот подход должен обеспечить более интерактивный интерфейс, аналогичный стандартному браузеру, позволяя правильно отображать контент, зависящий от JavaScript.

Другие вопросы по теме

Похожие вопросы

Как устранить ошибку «Канал безвозвратно испорчен и будет удален!»
Ошибка сборки Android: повторяющийся класс с Protobuf при добавлении обмена сообщениями Firebase в приложении
Указанный RuntimeIdentifier «android.21-arm64» не распознан
Как передать делегатов из Unity C# в собственный Kotlin Android SDK?
Превышены ограничения памяти плиток Unity+Android, некоторый контент может не отрисовываться
Как создать составной элемент, который отображает текст песни с аккордами над словами?
Пытаюсь выяснить предупреждение «Ресурс не удалось закрыть» в моем приложении для Android
Paging3 метод pagingdata InsertHeaderItem не может вставить несколько фрагментов данных
Andoird [Bluetooth LE] создает характеристику с заранее заданным значением перед рекламой услуги на периферийном устройстве (приложение для Android)
[Android][ Отправка голосового ввода на Android TV с помощью пульта дистанционного управления Android TV v2