Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] 로스트아크 캐릭터 정보 불러오기 #8

Open
BiteSnail opened this issue Jan 26, 2023 · 2 comments
Open

[Feature] 로스트아크 캐릭터 정보 불러오기 #8

BiteSnail opened this issue Jan 26, 2023 · 2 comments
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@BiteSnail
Copy link
Collaborator

로스트아크 자유게시판에서 글쓴이의 정보를 확인할 때에 아래와 같은 정보가 나옵니다. 여기에서 우리가 주목해야 하는 부분은 전투정보실 버튼에 있는 data-url입니다.
해당 버튼에 물려있는 Member?id=...부분을 통해 설정된 대표캐릭터로 이동하는 것을 알 수 있었습니다. 그래서 이 부분이 생성되는 곳을 조사하였습니다.

<div class="user-info">
    <div class="user-thumb">
        <img src="https://cdn-lostark.game.onstove.com/uploadfiles/badge/03dd4962d07e44de8c82836ff795b274.png" alt="신규 모험가">
    </div>
    <div class="member-info" aria-label="닉네임">
        <span class="member-info__nickname" title="SKTT1페이커">SKTT1페이커</span>
    </div>
    <button type="button" class="button button--user-info" aria-haspopup="true" aria-expanded="false" data-memberno="84520949" data-nickname="SKTT1페이커">유저 정보</button>
    <span class="user-buttons">
        <button type="button" class="button button--user-profile" aria-haspopup="true" aria-expanded="false" data-memberno="84520949" data-nickname="SKTT1페이커">프로필</button>
        <button type="button" class="button button--user-battle" data-url="/Profile/Member?id=KjNd%2BmgJZ79PXA6Hb9hE2MdqHfKL9hfPLbm7E%2Bb%2BYjU%3D">전투정보실</button>
        <button type="button" class="button button--user-library" disabled="">베른대도서관 활동</button>
    </span>
</div>

그리고 소스파일을 뜯어보던 중에 해당 정보를 얻을 수 있는 부분을 찾았습니다. 아래는 원본인데 중요한 내용은 html += '<button type="button" class="button button--user-battle" data-url="/Profile/Member?id=' + encodeURIComponent(encryptMemberNo) + '" >전투정보실</button>';이 부분입니다.
위 코드를 통해서 id가 encrpytMemberNo을 URI 인코딩한 정보임을 알 수 있습니다. 따라서 encrpytMemberNo를 URI 인코딩하여 비교하면 캐릭터 조회할 수 있는 기능이 완성될 것 같습니다.

/* 공통 - 캐릭터 정보 조회 (2차) */
$(document).on('click', '.lostark-wrapper .button--user-info', function (e) { // 유저 정보 버튼 클릭시 리스트 노출
    var isCharacter = false;
    var isActivity = false;
    var encryptMemberNo = '';
    var memberNo = $(this).attr('data-memberNo');
    var nickName = $(this).attr('data-nickName');
    var _this = $(this),
        userinfo = _this.closest('.user-info');

    $.ajax({
        url: "/board/IsCharacterList",
        method: "POST",
        data: { memberNo: memberNo },
        async: false,
        success: function (data) {
            isCharacter = data.isCharacter;
            encryptMemberNo = data.encryptMemberNo;
        },
        error: function (xhr, status, error) {
            ajaxErrorHandler(xhr, status, error);
            return;
        }
    });

    $.ajax({
        url: "/board/IsActivity",
        method: "POST",
        data: { memberNo: memberNo },
        async: false,
        success: function (data) {
            isActivity = data.isActivity;
        },
        error: function (xhr, status, error) {
            ajaxErrorHandler(xhr, status, error);
            return;
        }
    });

    var html = '';
    html += '<span class="user-buttons">';
    html += '<button type="button" class="button button--user-profile" aria-haspopup="true" aria-expanded="false" data-memberNo=\"' + memberNo + '\" data-nickName=\"' + nickName + '\" >프로필</button>';

    if (isCharacter) {
        html += '<button type="button" class="button button--user-battle" data-url="/Profile/Member?id=' + encodeURIComponent(encryptMemberNo) + '" >전투정보실</button>';
    }
    else {
        html += '<button type="button" class="button button--user-battle"  disabled >전투정보실</button>';
    }

    if (isActivity) {
        html += '<button type="button" class="button button--user-library" data-url="/Library/Tip/UserList?page=1&searchtype=4&searchtext=' + encodeURIComponent(nickName) + '&ordertype=1&userPageType=1">베른대도서관 활동</button>';
    }
    else {
        html += '<button type="button" class="button button--user-library" disabled >베른대도서관 활동</button>';
    }

    html += '</span>';

    if (!userinfo.find('.user-buttons').length) userinfo.append(html);

    userinfo.toggleClass('user-info--active');

    e.preventDefault();
});

현재 HTML 상의 id : KjNd%2BmgJZ79PXA6Hb9hE2MdqHfKL9hfPLbm7E%2Bb%2BYjU%3D
encrpytMemberNo : Sztq0vl9H1WVr4xxWeQ8H1TK9h5UJMfn/CpWSFdEfcE=
URI인코딩 : Sztq0vl9H1WVr4xxWeQ8H1TK9h5UJMfn%2fCpWSFdEfcE%3d
HTML과 받아온 데이터가 달라서 안될 것 같았는데 정상적으로 작동한 것을 알 수 있었습니다. 그래서 시간에 따라 값이 바뀌는 것을 확인할 수 있습니다.

아래에 위 과정을 확인할 수 있는 코드를 올립니다.
memberNo만 본인 스토브 번호로 바꾸면 자신의 캐릭터들을 확인할 수 있습니다.

import requests
from urllib import parse

base_url = "https://lostark.game.onstove.com//Profile/Member?id="

response = requests.post(url="https://lostark.game.onstove.com/board/IsCharacterList",
                        data={"memberNo": "82661074"})

encrypt_member_no = response.json()['encryptMemberNo']
URI_encoding_encrypt_member_no = parse.quote(encrypt_member_no)

print(base_url+URI_encoding_encrypt_member_no)
@BiteSnail BiteSnail added the documentation Improvements or additions to documentation label Jan 26, 2023
@BiteSnail BiteSnail self-assigned this Jan 26, 2023
@BiteSnail
Copy link
Collaborator Author

조금 더 정리한 코드입니다.

import requests
from urllib import parse
from bs4 import BeautifulSoup

BASEURL = "https://lostark.game.onstove.com//Profile/Member?id="
CHARACTER_SELECTOR = "#lostark-wrapper > div > main > div > div.profile-character-info > span.profile-character-info__name"


def get_character_name(member_number: str):
    response = requests.post(url="https://lostark.game.onstove.com/board/IsCharacterList",
                             data={"memberNo": member_number})
    encrypt_member_no = ""
    character_name = ""
    if response.status_code == 200:
        print("encrypt_member_no: "+encrypt_member_no)
        encrypt_member_no = response.json()['encryptMemberNo']

    info_response = requests.get(BASEURL + parse.quote(encrypt_member_no))
    print("connect to "+BASEURL+parse.quote(encrypt_member_no))
    if info_response.status_code == 200:
        soup = BeautifulSoup(info_response.text, 'html.parser')
        character_name = soup.select_one(CHARACTER_SELECTOR).get_text()

    if character_name:
        return {"characterName": character_name}
    else:
        return {"characterName": ""}


if __name__ == "__main__":
    name = get_character_name("82661074")
    print(name)

@BiteSnail
Copy link
Collaborator Author

def auth_stove_account(member_number: str, auth_token: str) -> bool:
    response = requests.get('https://api.onstove.com/tm/v1/preferences/'\
                            + member_number)
    if response.status_code == 200:
        print(response.json()['data']['introduce'])
        return auth_token == response.json()['data']['introduce']
    return False

스토브 인증을 위한 소개글 불러오기

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

1 participant