- Я пытаюсь очистить веб-сайт, на котором есть аутентификация при входе.
- Мне удалось использовать библиотеку запросов Python, но когда я попытался преобразовать ее в Kotlin Ktor библиотека (чтобы реализовать ее в своем проекте Android). Я столкнулся с проблемой при запросе 3.
- Проблема началась, когда я отправил json в почтовом запросе. В коде Python я получаю заголовок set-cookies в заголовках ответа после отправки третьего запроса, но в котлине я не получил заголовок set-cookies и отображаемое тело ответа ошибка.
- Я не уверен, проблема в самом json или в заголовках.
- Вот мой код (я пытался изменить некоторые текст для конфиденциальности)
import requests
import urllib.parse
from bs4 import BeautifulSoup as bs
import random
import base64
import json
import time
p1 = {'p': '147:1::::::'}
purl1 = 'https://someURL/ords/f?p=147:1::::::'
purl3 = "https://someURL/ords/wwv_flow.accept"
def fetchp(username, password) -> tuple:
with requests.Session() as s:
r1 = s.get(purl1, params=p1, allow_redirects=False)
location = r1.headers['location']
r2 = s.get(location, allow_redirects=False)
soup = bs(r2.content, 'html.parser')
p_instance = purl2.split(":")[3]
pSalt = soup.find(id="pSalt")["value"]
pPageSubmissionId = soup.find(id="pPageSubmissionId")["value"]
P0_PROGRAM_NO = soup.find(id="P0_PROGRAM_NO").findNext()["value"]
P0_RELATION_DEGREE = soup.find(id="P0_RELATION_DEGREE").findNext()["value"]
P0_DOCS_URL = soup.find(id="P0_DOCS_URL").findNext()["value"]
pPageItemsProtected = soup.find(id="pPageItemsProtected")["value"]
p2 = {
"p_flow_id": 147,
"p_flow_step_id": 9999,
"p_instance": p_instance,
"p_debug": "",
"p_request": "LOGIN",
"p_reload_on_submit": "S",
"p_page_submission_id": pPageSubmissionId,
"p_json": json.dumps({
"pageItems": {
"itemsToSubmit": [
{
"n": "P0_PAGE_CLOSE_OPENED",
"v": ""
},
{
"n": "P0_PROGRAM_NO",
"v": "",
"ck": P0_PROGRAM_NO
},
{
"n": "P0_RELATION_DEGREE",
"v": "",
"ck": P0_RELATION_DEGREE
},
{
"n": "P0_DOCS_URL",
"v": "",
"ck": P0_DOCS_URL
},
{
"n": "P9999_USERNAME",
"v": username
},
{
"n": "P9999_PASSWORD",
"v": password
},
{
"n": "P9999_REMEMBER",
"v": []
}
],
"protected": pPageItemsProtected,
"rowVersion": "",
"formRegionChecksums": []
},
"salt": pSalt
})
}
r3 = s.post(purl3, data=p2, allow_redirects=False)
purl4 = f"https://someURL/ords/f?p=147:1:{p_instance}:::::"
r4 = s.get(purl4, allow_redirects=False)
soup = bs(r4.content, 'html.parser')
print(r4.text)
# return (s, serial)
fetchp("username", "password")
< /code>
kotlin < /h3>
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.plugins.cookies.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.json.*
import kotlinx.serialization.encodeToString
import org.jsoup.Jsoup
import kotlin.system.measureTimeMillis
class SLogin {
companion object {
private const val u1 = "someURL/ords/f?p=147:1::::::"
private const val u3 = "someURL/ords/wwv_flow.accept"
}
private val client = HttpClient(OkHttp) {
install(HttpCookies)
expectSuccess = false
followRedirects = false
}
fun login(username: String, password: String): String = runBlocking {
// Step 1: Initial GET request to u1
val r1 = client.get(u1) {
parameter("p", "147:1::::::")
}
printRequestAndResponse(1, r1)
val location = r1.headers["Location"]!!
val cookies = r1.headers["Set-Cookie"]!!.split(";")[0] //passing same cookies as r2 to r3 because for some reason they are not kept in session
println("Cookies from r2: $cookies")
val r2 = client.get(location)
printRequestAndResponse(2, r2)
val soup = Jsoup.parse(r2.bodyAsText())
val pInstance = location.split(":")[3]
val pSalt = soup.select("#pSalt").attr("value")
val pPageSubmissionId = pSalt
val p0ProgramNo = soup.select("#P0_PROGRAM_NO").next().attr("value")
val p0RelationDegree = soup.select("#P0_RELATION_DEGREE").next().attr("value")
val p0DocsUrl = soup.select("#P0_DOCS_URL").next().attr("value")
val pPageItemsProtected = soup.select("#pPageItemsProtected").attr("value")
val pJson = buildJsonObject {
putJsonObject("pageItems") {
putJsonArray("itemsToSubmit") {
addJsonObject { put("n", "P0_PAGE_CLOSE_OPENED"); put("v", "") }
addJsonObject { put("n", "P0_PROGRAM_NO"); put("v", ""); put("ck", p0ProgramNo) }
addJsonObject { put("n", "P0_RELATION_DEGREE"); put("v", ""); put("ck", p0RelationDegree) }
addJsonObject { put("n", "P0_DOCS_URL"); put("v", ""); put("ck", p0DocsUrl) }
addJsonObject { put("n", "P9999_USERNAME"); put("v", username) }
addJsonObject { put("n", "P9999_PASSWORD"); put("v", password) }
addJsonObject { put("n", "P9999_REMEMBER"); put("v", JsonArray(emptyList())) }
}
put("protected", pPageItemsProtected)
put("rowVersion", "")
put("formRegionChecksums", JsonArray(emptyList()))
}
put("salt", pSalt)
}
val p2 = buildJsonObject {
put("p_flow_id", 147)
put("p_flow_step_id", 9999)
put("p_instance", pInstance)
put("p_debug", "")
put("p_request", "LOGIN")
put("p_reload_on_submit", "S")
put("p_page_submission_id", pPageSubmissionId)
put("p_json", pJson.toString())
}
val jsonPayloadString = Json.encodeToString(p2)
// println("JSON Payload: $jsonPayloadString")
val r3 = client.post(u3) {
contentType(ContentType.Application.FormUrlEncoded)
setBody(jsonPayloadString)
headers {
append("Cookie", cookies!!)
}
}
printRequestAndResponse(3, r3)
println("body: ${r3.bodyAsText()}")
val purl4 = "someURL/ords/f?p=147:1:${pInstance}:::::"
val r4 = client.get(purl4)
printRequestAndResponse(4, r4)
return@runBlocking r4.bodyAsText()
}
fun close() {
client.close()
}
}
suspend fun printRequestAndResponse(number: Int, response: HttpResponse, requestBody: String? = null) {
println("=== Request Details ===")
println("Request $number")
println("Request URL: ${response.request.url}")
println("Request method: ${response.request.method}")
println("Request headers: ${response.request.headers}")
if (requestBody != null) {
println("Request body: $requestBody")
} else {
println("Request body: [No body or not logged]")
}
println("=== Response Details ===")
println("Response status: ${response.status}")
val headers = response.headers.entries().joinToString(", ") { (key, values) ->
"$key=${values.joinToString(", ")}"
}
println("Response headers: $headers")
// println("Response body: ${response.bodyAsText()}")
println("========================\n")
}
fun main() {
val loginService = SLogin()
val username = "username"
val password = "password"
val elapsedTime = measureTimeMillis {
val response = loginService.login(username, password)
println("Login response: $response")
}
println("Elapsed time: ${elapsedTime}ms")
loginService.close()
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... otlin-ktor