마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

Retrofit2를 이용해 크롤링을 하는데 json 객체가 []로만 표시됩니다

0 추천

안녕하세요. 처음 어플을 만들고 있는 초보 개발자입니다.

다름이 아니라 이번에 크롤링이 필요한 부분이 있어 retrofit2를 이용해 json이나 html 객체를 받아와야 합니다.

일단 json형태로 response되는 사이트를 크롤링하려고 하는데 연결은 되나 자료가 [] 으로만 뜨네요.

자세한 코드는 아래 첨부하겠습니다.

부디 답변 부탁드립니다.....

 

main.kt

val request = BeatPhobia_request(shop="던전101", quest="MST 엔터테인먼트", quest2="MST 엔터테인먼트", date=20220310)

        RetrofitClient.instance.postFirst(request)
            .enqueue(object: Callback<BeatPhobia_response>{
                 override fun onResponse(
                     call: Call<BeatPhobia_response>,
                     response: Response<BeatPhobia_response>
                 ) {
                    if(response.isSuccessful){
                        if (response.code() == 200) {
                            var result: BeatPhobia_response? = response.body()
                            Log.d("YMC", "Response successed\n" + result.toString())
                        }
                    }else{
                        Log.d("YMC", "Response failed")
                    }
                }

                override fun onFailure(call: Call<BeatPhobia_response>, error: Throwable) {
                    Log.d("YMC","Failure: " + error.message.toString())
                }
            })

 

RetrofitClient.kt

package com.example.exercise1.Retrofit

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitClient{
    private val BASE_URL = "https://www.xphobia.net"
//
    val instance: RetrofitService by lazy {
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        retrofit.create(RetrofitService::class.java)
    }
}

 

RetrofitService.kt

package com.example.exercise1.Retrofit

import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.POST

interface RetrofitService{

    private val Base_URL : String
        get() = "https://www.xphobia.net"

    @POST("/reservation/ck_date2_no1.php")
    fun postFirst(
        @Body params: BeatPhobia_request
    ) : Call<BeatPhobia_response>
}

 

Logcat

2022-03-08 01:29:49.631 13679-13679/com.example.exercise1 D/YMC: Response successed
    []

 

감사합니다.

erubusv (120 포인트) 님이 2022년 3월 8일 질문
참고로 파이썬에서 해당 api를 테스트했을 때는 정상적으로 데이터가 받아와졌습니다.
해당 사이트의 Form data

shop: 던전101

quest: MST 엔터테인먼트

quest2: MST 엔터테인먼트

date: 20220310

1개의 답변

0 추천

Retrofit을 사용할 때 BaseURL은 "/" 로 끝이 나야 하는 걸로 아는데요. 아래처럼 바꾸어 보세요.

object RetrofitClient{
    private val BASE_URL = "https://www.xphobia.net/" // 끝이 '/'로 끝나도록 변경

    val instance: RetrofitService by lazy {
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        retrofit.create(RetrofitService::class.java)
    }
}



interface RetrofitService {
    //private val Base_URL : String. ==> 중복이므로 삭제
            //get() = "https://www.xphobia.net"

    @POST("/reservation/ck_date2_no1.php")

    fun postFirst(
        @Body params: BeatPhobia_request
    ) : Call<BeatPhobia_response>
}

 

그리고 Retrofit의 response를 체크할 때,

if (response.code() == 200) 

200일 것만 필터를 하셨는데, 대부분의 경우는 맞지만,  좀 더 안전하게 하려면 Http응답코드를 보면 200 - 299를 정상 응답이라고 볼 수도 있습니다. 그리고 200 인 것만 성공으로 보시려면, 아래와 같은 로직으로 처리가 되어야 하지 않을 까 생각합니다.

왜냐하면  현재는 response.code가 200이 아닌 경우에 대한 처리를 해주고 있지 않기 때문입니다.

if(response.isSuccessful && response.code() == 200){
    val result: BeatPhobia_response? = response.body()
    Log.d("YMC", "Response successed\n" + result.toString())
 }else{
    Log.d("YMC", "Response failed")
 }

마지막으로, 코틀린을 사용하신다면 Coroutine을 사용하고 네트워크 작업을 하는 것이 자연스런 선택같아 보입니다. 랭귀지에서 제공하는 기능이니 별다른 라이브러리도 필요없고 콜백보다 성능이나 코드 면에서 더 나은 방법이라고 보입니다.

BaseURL을 고쳐서 되지 않는다면, Postman같은 툴로 먼저 테스트를 해보시고, 그래도 안된다면 구체적인 에러메세지를 올려보세요. 대부분은 서버에서 필요한 request 대로 처리를 하지 않아서 생기는 문제입니다.

spark (188,520 포인트) 님이 2022년 3월 8일 답변
안녕하세요. 정성스러운 답변 감사드립니다. 말씀하신 대로 url 끝에 /를 넣어줘도 똑같이 빈 배열을 받아오고 postman의 경우는 받아 오질 않네요. 파이썬으로 requests.post(url, form)을 요청했을 때는 정상적으로 받아와 지는 것이 확인됩니다. 이런 경우 무엇이 문제일까요..?
혹시 로그는 찍어보셨나요. Retrofit에 OKHttp3 + LogginInterceptor 를 붙어셔 실제적으로 어떤 데이터가 오가는지 확인해 보세요.

https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor
https://riptutorial.com/android/example/9327/retrofit-with-okhttp-interceptor

LoggingInterctpor를 이용하면 헤더와 바디 모두 확인이 가능하므로 어떤 부분이 서버에 필요한 요청값과 맞지 않는지 비교해 보세요.  Python 클라이언트의 값과 비교해 볼 수 있으면 좋을 것 같네요.
...