본문 바로가기

Swift

#Postman 이용하여 #대부분의 데이터를 받아오는 방법!

반응형

이미 존재하는 서비스를 활용하여 만드는 경우, 해당 서비스가 사용하는 (그러나 개인에게는 제공되지 않는) API를 활용하여 데이터를 받아와야 하는 경우가 생깁니다. 그리고 절차를 밟지 않고 API를 사용하면, 아무리 네트워크를 보고 흉내내서 만들어도 도도하게 400 에러를 튕깁니다.

다행히 브라우저는 다양한 방법을 제공하고 있습니다. 먼저 소개할 방법은 해당 네트워크 통신을 콘솔에서 Fetch로 사용해보며 이것저것 바꿔보는 것입니다.

해당 방식을 사용하면 브라우저가 데이터를 불러올 때 사용한 것과 동일한 방식으로 데이터를 받아올 수 있습니다. 물론 이렇게 복사한 코드는 동일 출처 정책에 따라 같은 도메인을 가진 페이지에서만 사용할 수 있습니다. (브라우저 확장 프로그램의 경우에는 이를 의도적으로 우회하여 사용할 수도 있습니다.)

await fetch("https://papago.naver.com/apis/langs/dect", {
    "credentials": "include",
    "headers": {
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0",
        "Accept": "application/json",
        "Accept-Language": "ko",
        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
        "device-type": "pc",
        "Timestamp": "1611131688488",
        "Authorization": "PPG 4193f39a-d5b6-47d4-8645-c31d39ac80ab:sF0euSNV9hgMjzmQ4ekHgA=="
    },
    "referrer": "https://papago.naver.com/",
    "body": "query=hello%20world",
    "method": "POST",
    "mode": "cors"
});

데이터를 받아오는 코드를 자바스크립트 형태가 아닌, 다양한 프로그래밍 언어에서 사용하기 위해선 또다른 방법이 필요합니다. 다음과 같이 명령어를 fetch 대신 cURL 명령어로 복사할 수 있습니다.

curl 'https://papago.naver.com/apis/langs/dect' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0' -H 'Accept: application/json' -H 'Accept-Language: ko' --compressed -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'device-type: pc' -H 'Timestamp: 1611131688488' -H 'Origin: https://papago.naver.com' -H 'Authorization: PPG 4193f39a-d5b6-47d4-8645-c31d39ac80ab:sF0euSNV9hgMjzmQ4ekHgA==' -H 'Referer: https://papago.naver.com/' -H 'Connection: keep-alive' -H 'Cookie: NNB=43FFSQ4UXQ6F6; NRTK=ag#20s_gr#2_ma#-2_si#-2_en#0_sp#-2; ASID=daedb86f000001741627d34600000060; NaverSuggestUse=use%26unuse; _ga=GA1.2.113949078.1601380156; _ga_7VKFYR6RV1=GS1.1.1611129940.44.1.1611131688.21; _ga_4BKHBFKFK0=GS1.1.1602689859.1.1.1602689927.60; nx_ssl=2; page_uid=U/J13wprvxZss75MAcwssssssl0-247444; JSESSIONID=6577D3AA4463DBDAE842E9D8DF177D78; papago_skin_locale=ko; pcview=pcview; BMR=s=1611114465990&r=https%3A%2F%2Fm.blog.naver.com%2FPostView.nhn%3FblogId%3Dilinkyou%26logNo%3D30189771399%26proxyReferer%3Dhttps%3A%252F%252Fwww.google.com%252F&r2=https%3A%2F%2Fwww.google.com%2Furl%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D%26ved%3D2ahUKEwi3yt6Vx6nuAhWYHXAKHWMmBjoQFjAAegQIAhAC%26url%3Dhttp%253A%252F%252Fm.blog.naver.com%252Filinkyou%252F30189771399%26usg%3DAOvVaw089R9jCeuxUSv38qrZ4pCY; _gid=GA1.2.585589463.1611073371' -H 'TE: Trailers' --data-raw 'query=hello%20world'

curl을 사용할 수 있는 bash 등에서는 이대로 사용해도 좋지만, 아무래도 정돈이 더 필요해 보입니다. 편리하게 정돈하기 위해서는 Postman이 필요합니다. Postman은 API 개발을 위한 협업 플랫폼으로, API 구축의 각 단계를 단순화하고 협업을 간소화하여 더 나은 API를 더 빠르게 만들 수 있습니다. 

www.postman.com/downloads/

 

Download Postman | Try Postman for Free

Try Postman for free! Join 13 million developers who rely on Postman, the collaboration platform for API development. Create better APIs—faster.

www.postman.com

Postman은 네트워크 request 옵션을 손쉽게 조작할 수 있고, 콜렉션 별로 request를 저장할 수 있다는 점에서 아주 매력적인 어플리케이션입니다.

Postman은 cURL 명령을 Import하여 다양한 프로그래밍 언어로 Export 하는 기능을 제공합니다. cURL 이외에도 RAML, WADL, OpenAPI 파일을 Import 할 수 있습니다.

Raw Text 탭으로 이동하여 이전에 복사했던 cURL 명령어를 붙여넣고 Continue, Import 버튼을 누릅니다.

추가된 Request를 확인해봅니다. Request Method나 Header가 모두 올바르게 추가되었고, Body는 raw 형태로 입력이 되었네요. 이는 Request의 형태에 따라 모두 다를 것 같습니다. 중요한 건 Send 버튼을 눌렀을 때 원하던 결과가 표시된다는 점이겠지요^^*

다음으로 해당 request를 Swift 코드 형태로 사용할 수 있도록 Export 해야 합니다. Send 버튼 오른쪽 아래에 있는 Code를 클릭하면 Generate Code Snippets 윈도우가 표시됩니다. 이 창에서 C, C#, Go, Java, Python, Swift 등 다양한 언어를 선택할 수 있으며, Swift의 경우 URLSession으로, Javascript의 경우 Fetch, jQuery, XHR 등 사용할 수 있는 라이브러리의 종류 또한 다양하게 제공됩니다.

import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

var semaphore = DispatchSemaphore (value: 0)

let parameters = "query=hello%20world"
let postData = parameters.data(using: .utf8)

var request = URLRequest(url: URL(string: "https://papago.naver.com/apis/langs/dect")!,timeoutInterval: Double.infinity)
request.addValue("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0", forHTTPHeaderField: "User-Agent")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("ko", forHTTPHeaderField: "Accept-Language")
request.addValue("application/x-www-form-urlencoded; charset=UTF-8", forHTTPHeaderField: "Content-Type")
request.addValue("pc", forHTTPHeaderField: "device-type")
request.addValue("1611131688488", forHTTPHeaderField: "Timestamp")
request.addValue("https://papago.naver.com", forHTTPHeaderField: "Origin")
request.addValue("PPG 4193f39a-d5b6-47d4-8645-c31d39ac80ab:sF0euSNV9hgMjzmQ4ekHgA==", forHTTPHeaderField: "Authorization")
request.addValue("https://papago.naver.com/", forHTTPHeaderField: "Referer")
request.addValue("keep-alive", forHTTPHeaderField: "Connection")
request.addValue("NNB=43FFSQ4UXQ6F6; NRTK=ag#20s_gr#2_ma#-2_si#-2_en#0_sp#-2; ASID=daedb86f000001741627d34600000060; NaverSuggestUse=use%26unuse; _ga=GA1.2.113949078.1601380156; _ga_7VKFYR6RV1=GS1.1.1611129940.44.1.1611131688.21; _ga_4BKHBFKFK0=GS1.1.1602689859.1.1.1602689927.60; nx_ssl=2; page_uid=U/J13wprvxZss75MAcwssssssl0-247444; JSESSIONID=6577D3AA4463DBDAE842E9D8DF177D78; papago_skin_locale=ko; pcview=pcview; BMR=s=1611114465990&r=https%3A%2F%2Fm.blog.naver.com%2FPostView.nhn%3FblogId%3Dilinkyou%26logNo%3D30189771399%26proxyReferer%3Dhttps%3A%252F%252Fwww.google.com%252F&r2=https%3A%2F%2Fwww.google.com%2Furl%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D%26ved%3D2ahUKEwi3yt6Vx6nuAhWYHXAKHWMmBjoQFjAAegQIAhAC%26url%3Dhttp%253A%252F%252Fm.blog.naver.com%252Filinkyou%252F30189771399%26usg%3DAOvVaw089R9jCeuxUSv38qrZ4pCY; _gid=GA1.2.585589463.1611073371", forHTTPHeaderField: "Cookie")
request.addValue("Trailers", forHTTPHeaderField: "TE")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in 
  guard let data = data else {
    print(String(describing: error))
    semaphore.signal()
    return
  }
  print(String(data: data, encoding: .utf8)!)
  semaphore.signal()
}

task.resume()
semaphore.wait()

이제 제공되는 코드를 입맛대로 바꿔 사용하시면 됩니다 하하~ 참 쉽죠? 프로그래밍의 여러 부분은 최초에 방법을 몰라서 문제지, 한 번 알고나면 참 다양하고 또 편리한 것 같습니다. "대부분의" 데이터를 받아오는 방법인 이유는.... 언제나 예외는 존재하기 때문이죠~~

반응형