다양한 서비스 고객센터의 QnA를 크롤링하는 작업 내용을 기록
service_1
: 기업명 ex) kakao 고객센터, coupang 고객센터 등service_2
: 서비스명 ex) 카카오톡, 카카오 계정 등category_1
: 대분류 카테고리 ex) 결제, 배송상품 등category_2
: 소분류 카테고리 ex) 할인쿠폰, 해외결제 등device
: 기기별 QnA가 다르기 때문에 기기 선택 ex) 공통, Android, iOS 등question
: 질문answer
: 응답link
: 질문 링크 (없으면 카테고리 링크)고객센터 QnA 데이터를 크롤링 후 데이터를 검수하는 작업이 필요합니다. 모든 데이터를 일일이 검수할 수는 없지만 하나의 소분류 카테고리 내에서 QnA 데이터 검수 작업을 진행합니다. (일반적으로 모두 비슷한 형식이기 때문에 하나의 카테고리만 검수해도 문제가 없었음)
주로 질문, 응답 첫 부분에 불필요한 내용이 포함되어 있는 경우가 많습니다. 데이터 검수 작업에서 불필요한 내용 확인 후 수정된 내용을 적용합니다.
주문목록
< 과 같이 텍스트에 링크가 걸려있는 경우 클라이언트에서 처리하기 쉽도록 크롤링 과정에서 <text|내용|링크>
와 같은 형식으로 변환하여 관리하였습니다.
ex) 교환/반품하기 마이쿠팡 → <text|주문목록|https://www.example.com> → 상품선택 …
주로 응답 내용 중간에 이미지가 삽입되어 있는 경우가 많습니다. 또한, 일반적으로 이미지는 링크로 접근할 수 있어 텍스트 링크 처리 방식과 비슷하게 <image|링크>
와 같은 형식으로 변환하여 관리하였습니다.
ex) 아래의 순서에 따라 진행해 주시기를 부탁 드립니다. 1. 고급탭 > 고급 설정 복원 버튼을
클릭해주세요. <image|https://www.example.com> 2. 열려있는 IE(익스플로러)브라우저를 ...
위의 이미지 처리 시 <image|링크>
로 변환하여 관리하였습니다. 하지만, 그림과 같은 설정 아이콘의 경우는 이미지 처리가 필요가 없습니다. 왜냐하면 처리된 이미지는 응답 내용에 필요한 가이드로 사용되는 이미지들을 처리하는 것이며 앱에서 보여주게 될 때 하나의 메시지 형식으로 이미지가 들어가게 될 것입니다. 그러므로, 이미지가 아이콘인지 가이드에 필요한 사진인지 구분을 해야합니다.
아이콘과 사진의 정확한 기준을 찾기 힘들었습니다. 일반적으로 아이콘은 width, height이 50 이하가 대부분이었습니다. (확인한 바로는 최대 32) 그래서 가로 세로 길이를 기준으로 구분하게 되었습니다. 아이콘의 경우 <icon>
으로 변환하여 관리합니다. (현재는 해당 icon을 따로 사용하지는 않습니다.)
GPT 토큰 제한으로 응답이 너무 길 경우 짤라줘야한다. 일반적으로는 응답이 길면 1500자로 토큰 제한에 문제가 되지 않는다. 하지만, 가끔 5000자를 넘어가는 응답이 존재한다. (대학교 목록) 그렇기에, 3000자가 넘어가는 응답의 경우 “답변이 너무 길이 링크를 참고해주세요” 라는 응답으로 수정하여 관리한다.
대분류, 소분류 카테고리 존재
카테고리 하나만 존재
# 더보기 버튼만 존재하는 경우
more_button_selector = 'button.ccs_btn_more'
next_page_button_selector = ''
더보기 버튼을 클릭했을 때 3가지 경우로 분류될 수 있다.
→ button 요소를 찾을 수 없는 경우를 처리하도록 구현하여 예외가 발생해 안전하게 종료된다.
→ button 요소는 남아있으나 class 명이 수정되어 button을 찾을 수 없다고 판단하며, 예외가 발생해 안전하게 종료된다.
→ button 요소가 남아있고 class명이 변경되지 않는다. 그러나, button 내부의 텍스트가 “더보기” → “마지막 리스트” 로 변경되기 때문에 클릭 전의 button 요소도 변경되어 사용할 수 없게 된다.
그렇기 때문에, 버튼 클릭 시 이전 버튼 요소가 사라질 때까지 기다린 뒤에 다시 버튼 요소를 가져와 클릭하게끔 수정하였다.
WebDriverWait(driver, 5).until(EC.staleness_of(button)) # 만약 더보기 버튼 요소가 클릭때마다 변경되면 활성화
기존의 이미지 처리는 width or height 가 50초과일 때 image 처리, 이하일 때 icon 처리로 구분되었다. 그러나, 다른 고객센터 크롤링 중 이미지 처리가 되지 않는 문제가 발생해 확인해 본 결과 width, height 가 정의되어 있지 않았다.
이 문제를 해결하기 위해 기존에 attribute를 가져오는 방식에서 url로 이미지를 연결하여 가져온 이미지의 size를 가져오는 방식으로 문제를 해결하였다.
# 이전 코드
img_tags = soup.find_all('img')
for img_tag in img_tags:
width = img_tag.get('width')
height = img_tag.get('height')
# 수정된 코드
img_response = requests.get(url)
img_data = BytesIO(img_response.content)
img = Image.open(img_data)
width, height = img.size
이 앱은 질문에 대한 답변을 처리할 때 참고한 문서의 링크로 연결할 수 있도록 되어있다. 하지만, 일부 고객센터만 질문에 대한 링크가 존재하고 다른 고객센터들은 자바 스크립트로 처리되어 있어 질문 링크를 줄 수 없다. 그래서 질문에 대한 링크가 없다면 디바이스, 디바이스 링크가 없다면 소분류 카테고리, 소분류 카테고리 링크가 없다면 대분류 순으로 링크를 주도록 처리했다.
기존에는 카테고리 개수가 많지 않고 대부분의 고객센터의 카테고리에는 링크가 존재했다. 그리고, 크롤링 할 필요가 없는 카테고리도 존재했기 때문에 크롤링 할 카테고리의 링크를 관리하여 해당 링크들로만 연결하여 크롤링을 진행하였다.
예를 들어, 쿠팡 고객센터의 경우 각 카테고리 별로 categoryCode
가 존재했다. 그래서 categoryCode를 모두 리스트에 정의하여 크롤링을 진행하였다.
하지만, 네이버 페이 고객센터의 크롤링을 진행할 때 카테고리 링크가 존재하긴 했지만 양이 너무 많았다.
일일이 모든 카테고리들의 링크를 정의하기엔 시간이 오래 걸렸고 기존에 카테고리 링크를 연결하여 페이지를 여는 방법을 카테고리 버튼을 클릭하여 페이지를 여는 방법으로 수정하였다.
즉, for문을 돌며 대분류 카테고리를 모두 클릭하고 내부 for문에서는 소분류 카테고리를 모두 클릭하면서 순차적으로 카테고리의 QnA를 크롤링하는 방식이다.
QnA에서 Answer을 크롤링할 때 고려해야하는 점이 3가지가 있다.
이 경우는 답변이 보이지 않아도 모든 응답 요소가 html 에 존재하여 어떤 동작을 할 필요 없이 답변을 바로 크롤링할 수 있다.
이 경우는 질문을 클릭하면 응답 요소가 나오게 된다. 다른 질문을 클릭하더라도 이전에 나온 응답 요소는 유지가 되며 해당 페이지를 크롤링 하기 위해서는 크롤링 전에 모든 질문들을 다 클릭해 모든 응답 요소가 노출되도록 해야한다.
이 경우는 클릭한 질문에 대해서만 응답 요소가 보이는 것이다. 그래서 위와 같은 방식으로 모든 질문들을 다 클릭하더라도 모든 응답 요소가 보이지 않는다. 그래서 질문 하나를 클릭할 때마다 해당 Answer을 가져와야한다. 1번과 2번 방식 모두 3번의 방식으로도 커버가 가능하기 때문에 3번의 방식으로 채택되었다.