본문 바로가기
해피 코딩/Spring

[NaverOpenAPI] NaverSearchAPI를 사용하여 쇼핑 상품 검색하기

by happy-coding 2024. 7. 19.

[ 목표 ]

🔥 NaverSarchAPI를 사용하여, 쇼핑 검색 프로젝트를 만들기.

[ 진행 순서 ]

  1. 애플리케이션 등록하기 (API 이용 신청)
  2. 쇼핑 검색 준비사항 정보 보기
  3. Postman을 사용하여 상품 검색하기
  4. SpringBoot를 사용하여 상품 검색하기
  5. 검색어를 찾아주는 <b></b>태그 없애기

[ 1. 애플리케이션 등록하기 (API 이용 신청) ]

네이버 애플리케이션 등록 URL: https://developers.naver.com/apps/#/register

 

애플리케이션 - NAVER Developers

 

developers.naver.com

( 네이버 로그인 후 이용 가능 )


  • 애플리케이션 이름:  내가 등록할 애플리케이션 이름
  • 사용 API: 검색
  • 비로그인 오픈 API 서비스 환경: WEB 설정
  • 웹 서비스 URL: http://localhost:8080

[ 애플리케이션 등록 성공 ]

등록 성공시 Naver로 부터 Client ID, Client Secret을 발급 받는다


 

[  2. 쇼핑 검색 준비사항 정보 보기 ]

네이버에서 제공하는 쇼핑 검색 정보를 참조하도록 하자.

 

쇼핑 검색 준비사항 정보 보기 URL:

https://developers.naver.com/docs/serviceapi/search/shopping/shopping.md#%EC%82%AC%EC%A0%84-%EC%A4%80%EB%B9%84-%EC%82%AC%ED%95%AD

 

검색 > 쇼핑 - Search API

검색 > 쇼핑 쇼핑 검색 개요 개요 검색 API와 쇼핑 검색 개요 검색 API는 네이버 검색 결과를 뉴스, 백과사전, 블로그, 쇼핑, 웹 문서, 전문정보, 지식iN, 책, 카페글 등 분야별로 볼 수 있는 API입니다

developers.naver.com


[ 3. Postman을 사용하여 상품 검색하기 ]

네이버 쇼핑 검색 정보를 참조하여 Postman을 사용해 보자. 

 

1. 요청 URL 입력하기

검색어는 쿼리 스트링 형식으로 전달한다. "macbook"

2. Header에 Client ID, Client Secret 넣어주기

Value에는 Naver에서 발급받은 Client ID, Client Secret 넣어주기


3. 입력한 정보를 바탕으로 상품 검색

네이버에서 제공하는 쇼핑 검색 API를 사용하여 입력한 "macbook"에 대한 데이터를 10개 가져올 수 있다. 

  • start: 검색 시작 위치
  • display: 한 번에 표시할 검색 결과 개수

[ 4. SpringBoot를 사용하여 상품 검색하기 ]

SpringBoot를 사용하여 코드를 만들고 검색 요청을 받아보도록 하자.

 

[ build.gradle ]

dependencies {
    // json 의존성
    implementation 'org.json:json:20231013'

    // thymeleaf
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    // web
    implementation 'org.springframework.boot:spring-boot-starter-web'
    // lombok
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

 


[ Dto ]

NaverSearchAPI로 부터 받아오고 싶은 데이터
@Getter
@NoArgsConstructor
public class ItemDto {
  private String title;
  private String link;
  private String image;
  private int lprice;

  public ItemDto(JSONObject itemJson) {
    this.title = itemJson.getString("title");
    this.link = itemJson.getString("link");
    this.image = itemJson.getString("image");
    this.lprice = itemJson.getInt("lprice");
  }
}

[ Controller ]

@Controller
public class NaverApiController {

  private final NaverApiService naverApiService;

  public NaverApiController(NaverApiService naverApiService) {
    this.naverApiService = naverApiService;
  }

  @GetMapping("/")
  public String root(){
    return "index";
  }

  @GetMapping("/search")
  public String searchItems(
          @RequestParam
          String query,
          Model model
  )  {
    List<ItemDto> itemDtos = naverApiService.searchItems(query);
    model.addAttribute("items", itemDtos);

    return "index";
  }

}

[ Service ]

URI 객체
- NaverServerAPI의 주소, display(검색 결과 개수), query(내가 입력한 검색어)를 넣어준다.
RequestEntity 객체
- NaverAPI에서 정한 방식을 지정해준다.
- [ Get ] 방식, header에는 본인의 Client ID를 넣어준다.
NaverAPI에 데이터 보내고 받아오기
- exchange(): RestTemplate클래스에서 HTTP 요청을 보낼 때 사용
- ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
Naver API에서 받아온 Json형태의 데이터를 Dto형태로 변환하고 반환하기
- return fromJSONtoItems(responseEntity.getBody());
@Service
public class NaverApiService {

  private final RestTemplate restTemplate;

  // RestTemplate 주입
  public NaverApiService(RestTemplateBuilder builder) {
    this.restTemplate = builder.build();
  }

  public List<ItemDto> searchItems(String query) {
    // 요청 URL 만들기
    URI uri = UriComponentsBuilder
            .fromUriString("https://openapi.naver.com")
            .path("/v1/search/shop.json")
            .queryParam("display", 3) // 3개의 데이터를 받아온다
            .queryParam("query", query)
            .encode()
            .build()
            .toUri(); // UriComponentsBuilder에 입력한 데이터를 URI로 변환

    RequestEntity<Void> requestEntity = RequestEntity
            .get(uri)
            // Naver에서 발급받은 Client ID
            .header("X-Naver-Client-Id", "cMQm68CUzx_USWULztuV")
            // Naver에서 발급받은 Client Secret
            .header("X-Naver-Client-Secret", "Fnn5VZjRxJ")
            .build();

    // .exchange(RequestEntity, ResponseType)
    ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);

    return fromJSONtoItems(responseEntity.getBody());
  }

  // Naver에서 받아온 items데이터를 ItemDto 객체로 변환하여 리스트로 반환
  public List<ItemDto> fromJSONtoItems(String responseEntity) {
    JSONObject jsonObject = new JSONObject(responseEntity);
    JSONArray items  = jsonObject.getJSONArray("items");
    List<ItemDto> itemDtoList = new ArrayList<>();

    for (Object item : items) {
      ItemDto itemDto = new ItemDto((JSONObject) item);
      itemDtoList.add(itemDto);
    }

    return itemDtoList;
  }
}

[ 결과 확인 ]

검색창에 "맥북" 검색하기

검색 전

Dto에서 변수로 설정해준 title, linkUrl, imageUrl, lprice를 받아오는 모습을 볼 수 있다.
검색한 단어가 <b</b>태그에 담겨서 반환된 모습을 볼 수 있다.

검색 후


[ 4. 검색어를 찾아주는 <b></b>태그 없애기 ]

.replaceAll() 메서드를 사용하여 <b></b>태그를 없애준다.
 @GetMapping("/search")
  public String searchItems(
          @RequestParam
          String query,
          Model model
  )  {
    List<ItemDto> itemDtos = naverApiService.searchItems(query);
    List<ItemDto> result = new ArrayList<>();

    // title에서 <b></b> 없애기
    for (ItemDto item: itemDtos) {
      String itemTitle = item.getTitle().replaceAll("<b>|</b>", "");
      item.setTitle(itemTitle);
      // 수정한 데이터를 result에 넣어주기
      result.add(item);
    }
    
    // itemDtos -> result 수정
    model.addAttribute("items", result);

    return "index";
  }

[ 결과 확인 ]

<b></b>태그가 사라진 모습을 볼 수 있다.

HTML 정리


이로써 NaverSarchAPI를 사용하여 쇼핑 상품 검색 프로젝트를 만들어 보았다.

 

읽어 주셔서 감사합니다 😊

😺 Github : https://github.com/mad-cost/NaverOpenAPI-Search