Я работаю над проектом 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)
Все равно выдает ту же ошибку...
Я тестировал его с помощью Postman, и он работал пару раз, возвращая тело HTML-страницы, но после 10 попыток он вернет 403 Forbidden.
Вероятно, вы вызывали его слишком много раз за короткий период времени, и впоследствии он заблокировал ваш запрос.
Вы отправляете запросы на веб-сайт, который, вероятно, защищен брандмауэром (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.
Это не проблема отправки слишком большого количества запросов; Я это проверил. Интересно, что когда я использую веб-версию Postman, запрос выполняется без проблем. Однако тот же запрос через библиотеку Retrofit приводит к ошибке. Это заставляет меня подозревать, что Postman может включать определенные заголовки или выполнять некоторые фоновые операции, которые позволяют ему получить правильный ответ. Есть ли способ воспроизвести это поведение в Retrofit и добиться такого же успешного ответа?