문제상황

 

public class SignScript : MonoBehaviour
{
    public string text;
}

  다음과 같이 public으로 변수를 선언하면 unity 엔진에서 해당 변수의 값을 오브젝트마다 넣어줄 수 있다.

 

  이때 string의 경우 Enter는 입력되지 않고, \n과 같은 줄바꿈 문자를 삽입하더라도 줄바꿈이 일어나지 않는다.

  이는 입력한 \n을 \\n으로 인식해 작성한 그대로 화면에 출력하기 때문이다.

 

 

해결방법

 

1. Replace함수 사용

 

public class SignScript : MonoBehaviour
{
    public string text;
    // Start is called before the first frame update
    void Start()
    {
        text = text.Replace("\\n", "\n");
    }
}

  \\n을 \n으로 치환하면, 원래 역할인 줄바꿈을 당연히 잘 수행한다.

  하지만...

  • \t, \r 등 사용하는 특수문자마다 다 replace를 해줘야 한다
  • 정말로 화면에 "\n" 문자가 찍혀야 한다면 방법이 없다

  이런 문제점이 발생한다

 

 

2. TextArea 설정

 

public class SignScript : MonoBehaviour
{
    [TextArea]
    public string text;
}

  string 위에 [TextArea]를 선언하면, Unity의 Text입력부분이 여러줄 입력 가능한 큰 공간이 된다.

 

  이 공간에서는 Enter로 줄바꿈 입력이 가능하니 있는 그대로 입력해 사용할 수 있다.

 

※ 주의사항

  TextArea를 붙였다가 제거한 경우, 원래의 한줄 Text로 돌아오며 기존 입력의 최상위 한줄만 보이게 된다.

  하지만 실제로는 입력했던 값들이 다 그대로 남아 있으니, 제대로 삭제하지 않으면 2번째 줄부터는 그대로 유지되게 된다.

1. 화살이 부딫힌 오브젝트가 합당하면 (플랫폼/적) 실행된다

2. SetParent로 인한 scale 변경을 방지하기 위해 임시 부모를 생성한다

3. 임시 부모를 목표 부모(충돌체)에 자식으로 넣는다

4. stickArrow를 생성한다 (사용할 화살과 동일해 보이지만, script와 rigidBody나 collider가 제거된 오브젝트)

5. stickArrow를 임시 부모의 자식으로 넣는다

6. 2초 후 제거한다

(충돌 당시 방향으로 조금 이동시킨 후 작업하면 화살촉이 진짜로 박혀있는 듯 보일듯함)

private void OnCollisionEnter2D(Collision2D other)
{
    GameObject otherObject = other.gameObject;

    if (isArrow && (otherObject.CompareTag("Platform") || otherObject.CompareTag("Enemy")))
    {
        // scale 변경 방지용 쿠션 parent
        GameObject sharedParent = new GameObject("Father");
        sharedParent.transform.position = otherObject.transform.position;
        sharedParent.transform.rotation = otherObject.transform.rotation;
        sharedParent.transform.SetParent(otherObject.gameObject.transform);

        // 고정될 화살 생성
        GameObject newArrow = Instantiate(stickArrow, transform.position, transform.rotation);
        newArrow.transform.SetParent(sharedParent.transform, true);
        //2초 후 소멸
        Destroy(newArrow, 2);
    }
}

 

 

 

벽에 충돌해도 2초간 잘 남아있다

적에게 충돌하면, 2초간 적이 이동해도 따라 이동하며 남아있다 

  Twitter4j로 웹에서 자동으로 트윗할 수 있도록 하는 기능을 만들려고 했는데, 검색결과가 2015년 이후로는 거의 없다시피 하고, pin방식은 아예 없어서 작성해봅니다.

 

1. 트위터 앱 생성과 키 발급

 

  우선 앱이 있어야 사용자가 인증을 받을 수 있습니다

트위터_개발자_계정_취득하기 (2021년 글)

트위터_API_사용_준비 (2020년 글, 일부 UI의 차이)

 

  자세히 설명해 둔 블로그로 이 부분은 설명을 대체하겠습니다.

  *2021년들어 인증 절차가 까다로워졌다는 말이 있던데, 저는 정직하게 '내 서비스랑 연동해서 자동 트윗하는 봇 만들꺼다' 하고 보냈더니 별 추가 절차 없이 통과되었습니다. 

 

  개발자 계정을 잘 발급 받으시고, projects / app까지 생성하시면 다음과 같은 항목을 보실 수 있습니다.

  

  Access Token이 없으시면 APP - Keys and Tokens에서 발급받으시면 됩니다.

  모든 항목은 단 한번만 보여지며, 재발급시엔 기존 토큰들이 날아가는 듯 하니 어딘가 저장해놓고 사용하는게 좋겠습니다.

 

  Access Token을 이용하면, 트위터 로그인 과정 없이도 자바 코드상에서 인증받고, 트윗을 쓰고, RT하고, 답글을 다는 등 트위터 이용이 가능합니다.

 

  하지만 이 때 사용되는 계정은 app을 생성한 개발자 계정입니다. 지금 저는 봇계정을 만들어 그쪽에서 자동으로 트윗되도록 하고 싶은 상황이니, 본 계정을 사용할 수 있다고 해도 별 소용이 없습니다.

 

  이럴때 사용하는 게 위의 Consumer key / secret입니다. 이 값들로 우리는 다른 계정에게 Access Token 요청을 보낼 수 있으며, 요청이 수락되면 그 계정의 Access Token을 얻어 조작할 수 있게 되죠.

 

익숙한 이미지

  트위터 앱 승인 함부로 하면 안된다는 이유가 이겁니다. ID / PW가 해킹당하지 않더라도 재미있는 서비스 앱을 승인해줬는데 어느순간 내 계정에 광고가 올라오는 상황이 발생할 수 있는 것이죠.

 

  이만 각설하고, Consumer key / secret으로 다른 계정의 Access Token 획득 방법에 대해 알아보겠습니다.

 

2. 해당 키로 인증해 pin 발급받기

 

  우선, JAVA에서 twitter 서비스를 사용할 수 있게 해주는 라이브러리를 추가해야 합니다.

  twitter4j 다운받기

  

  여러 jar 파일 중 twitter4j-core-x.x.x파일만 사용해도 충분합니다

 

  우선 위에서 취득한 Consumer key / secret을 이용해 사용자에게 앱 인증 요청을 보내야합니다.

 

//전역변수 선언
static String accessToken="";
static String accessSecret="";
	
static Twitter twitter;
RequestToken requestToken=null;
AccessToken finalAccessToken=null;

//twitter 객체 초기화 + consumer 인증 set
twitter = TwitterFactory.getSingleton();
twitter.setOAuthConsumer(TwitterInfo.getInstance().getAPIKey(), 
		TwitterInfo.getInstance().getAPISecretKey());

  twitter 객체를 획득한 후, setOAuthConsumer 함수를 이용해 Consumer의 key와 secret을 설정합니다.

  해당 함수는 2번째 실행부터는 에러가 발생한다고 하는데, singleton 패턴이 적용된 생성자 내부에서 실행하여 에러 발생을 막았습니다.

 

twitter = TwitterFactory.getSingleton();
		
requestToken=null;
try {
	requestToken = twitter.getOAuthRequestToken();
}catch(TwitterException e) {
	e.printStackTrace();
}
System. out.println(requestToken.getAuthorizationURL());
        

  그 후 getOAuthRequestToken() 함수를 이용해 requestToken을 획득합니다.

  requestToken.getAuthorizationURL() 의 값이 인증 URL입니다. 서버라면 이 주소로 redirect되도록 할 수 있습니다.

 

  그 후는 사용자가 트위터 계정을 로그인하고, 앱 사용 승인버튼을 눌러주면 됩니다.

 

3. pin으로 인증해 최종 accesstoken받기

 

  원래는 사용자가 승인버튼을 누르면, 인증정보를 담은 채 본래 인증창이 비롯된 페이지로 되돌아간다고 합니다.

  하지만 따로 돌아갈 url을 지정해놓지 않았거나, 저처럼 호스팅되지 않은 서버에서 온 요청같은 경우 이 방법은 사용할 수 없습니다.

 

  그래서 트위터는 7자리 숫자 pin을 제공하며, 서비스에서 해당 pin으로 다시 요청을 보내면 그 때 accessToken을 발급해 줍니다.

  대충 맨날 하는 문자인증과 비슷하다고 보시면 될 듯 합니다.

 

  처리 방법도 문자인증 방법과 비슷합니다. client에게 네가 받은 그 정보를 다시 나에게 달라고 요청하는 것이죠.

  (물론 제 경우는 서버도 client도 같은 시스템이므로 어떻게든 우겨넣기만 하면 상관없긴 합니다)

 

public void tweetGetAccessTokenTest(String pin) {
	try {
		finalAccessToken = twitter.getOAuthAccessToken(requestToken, pin);
	}catch(TwitterException e) {
		e.printStackTrace();
	}
}

  그렇게 받은 pin 정보는, 이전에 취득했던 requestToken과 함께 다시 한번 트위터에게 제출됩니다.

  getOAuthAccessToken함수를 이용합니다.

 

  이 과정까지 성공적으로 완료했다면, 정상적으로 AccessToken을 획득한 것으로 이제 이 계정은 제 맘대로 할 수 있는 겁니다. (안됩니다)

 

twitter.setOAuthAccessToken(finalAccessToken);
	try {
    	//계정명 획득
		User user = twitter.verifyCredentials();
		System.out.println(user.getScreenName());
		
        //계정에 트윗 등록
		String msg = "this is test tweet from application";
		Status status = twitter.updateStatus(msg);		
	}catch(Exception e) {
		e.printStackTrace();
}

정상적으로 출력 / 트윗되었다

  다음 코드와 같이, AccessToken을 Set해주기만 하면 사용자 ID를 가져올 수도 있고, 원하는 문자열로 트윗을 보낼 수도 있습니다.

 

4. AccessToken을 저장해 둬 재사용 가능하게 하기

 

  여기까지만 하면, 매번 AccessToken을 획득해야한다는 수고로운 일이 생깁니다.

  물론 그럴 필요는 없습니다. AccessToken만 저장해두면 언제든지 꺼내서 재사용이 가능해집니다.

 

  위에서 획득한 AccessToken은 Consumer key/secret처럼 key/secret 두가지 token으로 되어 있습니다.

  getToken() 함수와, getTokenSecret()함수가 각 token을 획득 할 수 있으며, 플젝에 직접 박아놓든, DB에 저장하거나 한 후 필요할 때 조회하면 됩니다.

 

twitter = TwitterFactory.getSingleton();
finalAccessToken=new AccessToken(TwitterInfo.getInstance().getAccessToken(), 
		TwitterInfo.getInstance().getAccessSecret());

twitter.setOAuthAccessToken(finalAccessToken);




try {
	User user = twitter.verifyCredentials();
	System.out.println(user.getScreenName());
	
	String msg = "this is test tweet from application";
	Status status = twitter.updateStatus(msg);
}catch(Exception e) {
	e.printStackTrace();
}

  저는 TwitterInfo class에 값을 직접 저장했으며, consumer token과 함께 생성자에서 호출해 설정하는 식으로 마무리했습니다.

 

 

  이상으로 twitter4j를 이용한 트위터 인증 획득 방법을 마치겠습니다.

 

2021.05.01 - [기타] - [WEB] Selenium으로 트위터 자동 로그인하기 (JAVA)

 

[WEB] Selenium으로 트위터 자동 로그인하기 (JAVA)

driver.get("https://twitter.com/"); //id wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"react-root\"]/div/div/div/main/div/div/div/div[1]/div[1]/div/form/div/div[3]/div")));..

nato-blog.tistory.com

  위 글에 써진 대로 트위터 / 그랑블루의 쿠키를 취득, 한번 로그인한 정보를 유지하도록 만들었다

 

0. 기획 변경

 

  처음에는 그랑블루 계정들을 다 흝으며 소환석 데이터를 얻어 볼 생각이었지만, 힘들겠다는 생각이 들었다.

 

  우선, 소환석은 이벤트 등으로 신규 소환석을 얻음에 따라 자주 변경되는 데이터이다. 데이터를 얻는건 어렵지 않지만, 바뀌는 데이터를 추적하는건 다른 문제이다.

 

  또한 현재 신규계정번호가 3000만을 넘었으며, 작년 했던 켐페인이 "유저수 2700만 기념 켐페인!" 이었단걸 생각하면 현재 유저수는 못해도 2800만에 근접하지 않았을까 싶었다.

  이 경우 1초에 1명씩 확인한다 하면 하루 14만명 확인이 가능하며, 총 200일은 돌려야 전체 유저를 확인하게 된다.

  그정도면 내가 친구를 납치해다 만두만 먹이며 그랑블루를 시키는 쪽이 더 빠르겠다 싶었다.

 

  그래서 특정랭크 이상의 유저만 관리하고, 일정 주기마다 데이터 갱신을 돌리는 식으로 하려고 생각해봤지만, (ex. 225랭크 이상인 유저가 40만이라면, 3~4일정도면 갱신 가능하다) 이 역시 처음 한번 분류하는게 힘들고, 랭크의 상승을 알기 힘들다는게 문제가 되었다.

 

  하여 기획을 변경해 게시판처럼 사람들이 자기 소환석 현황을 게시하고, 다른 사람들이 이를 확인할 수 있도록 하는 정도는 쉽게 만들수 있지 않을까 생각했다.

  기존 SNS/커뮤니티에 존재하던 친구찾기 게시글들을 한 장소에 모아놓는 느낌?

 

  여기서 게시판을 따로 사이트를 만들지 말고, 트위터에 게시글을 올리는 식으로 하면 좋겠다고 생각했다.

  트위터라면 누구나 쉽게 이용 가능하고, 검색 시스템같은것도 잘 지원해 조건 설정도 가능하니 말이다.

 

1. 플레이어 데이터 획득

 

  로그인 세션을 문제없이 취득했다면, 사용자 id만 있다면 누구든지 접근해서 데이터를 얻어낼 수 있다.

 

  그러므로 우선 어떤 데이터들을 획득할 지 정리해 클래스로 만들어 보았다.

  우선 입력된 id, 이름, 랭크(레벨)과 원 목적이던 14개의 소환석 정보를 획득토록 하였다.

  summon은 img태그에 저장된 이미지 주소를 저장하며, summonLevel은 text로 된 상세설명을 저장한다.

 

  데이터 추출은 간단하게, 해당 주소에 접속 후 html 태그를 찾아 내부 요소를 추출하는 식으로 간단하게 완료하였다.

 

  데이터 정상 추출을 확인하기 위해 이름, rank, 이미지를 표시할 뿐인 간단한 페이지를 만들었다.

 

 

  정상적으로 데이터를 띄우는 걸 볼 수 있다.

 

2. 이미지 추출, 합성

 

  저장한 이미지 url들은 ImageIO를 사용해 실제 image객체로 저장한 후, Graphics를 사용해 하나의 이미지로 합쳐주었다.

 

  배경이 될 이미지를 추출하고, png를 jpg로 변환한 후 graphics를 만든다.

 

  그리고 소환석들의 url으로 이미지를 추출해, size를 조정한 후 graphics로 그리도록 하였다.

 

 

  파일의 저장 경로는 해당 사용자의 id로 폴더를 만들어 저장하도록 했다.

 

 

  결과로 나온 이미지로, 엉망진창이지만.. 일단 의도한대로 작동한다는 점에 만족하고 다음 작업으로 넘어가기로 했다.

driver.get("https://twitter.com/");
//id
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"react-root\"]/div/div/div/main/div/div/div/div[1]/div[1]/div/form/div/div[3]/div")));
WebElement id = driver.findElement(By.xpath("//*[@id=\"react-root\"]/div/div/div/main/div/div/div/div[1]/div[1]/div/form/div/div[1]/div/label/div/div[2]/div/input"));
id.clear();
id.sendKeys(twitterID);
//pw
WebElement pw = driver.findElement(By.name("session[password]"));
pw.clear();
pw.sendKeys(twitterPW);

Thread.sleep(1000);
//login
WebElement login = driver.findElement(By.xpath("//*[@id=\"react-root\"]/div/div/div/main/div/div/div/div[1]/div[1]/div/form/div/div[3]/div"));
login.click();
Thread.sleep(500);

  1. 로그인 코드

  트위터 웹 페이지로 접속 후 ID칸에는 ID를, PW칸에는 PW를 넣고 로그인 버튼을 클릭하는 간단한 코드이다.

 

이런 것들

  문제점 : Selenium은 테스트 등을 자동화하기 위한 도구로서, 같은 동작을 수회~수십회 반복해야하는 경우가 많다.

  그리고 트위터 포함 많은 웹 사이트는, 올바른 ID/PW로 로그인하더라도 단기간에 로그인이 반복되면 이상으로 간주, 추가 인증을 요구한다

 

File file = new File("Twitter.data");
try {
	file.createNewFile();
	BufferedWriter bw = new BufferedWriter(new FileWriter(file));
	for(Cookie cookie : driver.manage().getCookies()) {
		bw.write((cookie.getName() + ";" + cookie.getValue() + ";"
			+cookie.getDomain() + ";" + cookie.getPath() + ";"
			+ cookie.getExpiry() + ";" + cookie.isSecure()));

		bw.newLine();
	}
	bw.close();
}catch (Exception e) {
	e.printStackTrace();
}

  2. 쿠키 저장

  기본적으로 Selenium으로 뭔갈하려 하면, 매 실행마다 새로운 크롬 창을 실행하게 된다.

  즉 '로그인 유지' 같은걸 체크한다 한들 이전에 로그인했던 정보는 사라진다는 뜻이다.

 

  로그인은 세션으로 관리되는데, 결국 세션은 쿠키로 저장되므로(맞나?) 쿠키를 따로 파일에 저장해둔 후 이를 복구하면 세션이 유지되는 효과를 볼 수 있다.

 

  위 코드는 driver에서 쿠키를 가져와 Twitter.data에 저장하는 코드이다.

  driver가 twitter.com을 지정하고 있으므로, 많은 쿠키들 중 트위터 관련 쿠키만 반환되어 저장되는 듯 하다.

  (트위터 관련 쿠키의 도메인 값은 twitter.com, .twitter.com 두가지를 확인할 수 있었다)

 

driver.get("https://twitter.com/");

File file = new File("Twitter.data");
BufferedReader br = new BufferedReader(new FileReader(file));

String readLine;
while((readLine = br.readLine())!=null) {
	StringTokenizer st = new StringTokenizer(readLine,";");
	String name = st.nextToken();
	String value = st.nextToken();
	String domain = st.nextToken();
	String path = st.nextToken();
	Date expiry = null;
	
	String val;
	if(!(val = st.nextToken()).equals("null")){
		System.out.println(val);
		SimpleDateFormat format =new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
		expiry = format.parse(val);
	}
	Boolean isSecure = new Boolean(st.nextToken()).booleanValue();
	Cookie cookie = new Cookie(name, value, domain, path, expiry, isSecure);
	System.out.println(cookie);
	driver.manage().addCookie(cookie);
}
br.close();

driver.get("https://twitter.com/");

  3. 쿠키 복원

  새로운 selenium연결을 하고자 할 때, 1번처럼 직접 로그인하는 대신, 2번에서 저장한 파일을 불러와 쿠키를 복구할 수 있다.

  시간이 지나 expiry값이 만료됨에 따라 재 로그인이 필요할수도 있겠지만, 매번 로그인하는것보단 훨씬 효율적으로 사용 가능하다.

 

  File을 불러오기 전에 twitter에 한번 접속하는 이유는 addCookie 메소드가 현재 url이 cookie의 domain값과 일치해야 하기 때문이라고 한다 (출처)

  아무튼 한번 접속해주지 않으면 invalid cookie domain 에러를 받게 된다

 

작동 화면

  직접 실행해보면, 로그인 입력 없이도 잘 작동하는걸 확인할 수 있다.

 

  (왜인지 움짤 길이가 잘린다.. 여기서 확인 가능하다)

1. 캡챠 피하기

 

SNS로 로그인하기

  캡챠 뚫는법을 알았으면 내가 구글에 가있지 않았을까..? 하고 있었는데, SNS를 연동해서 로그인하는 방법이 존재한다는걸 알았다.

  그렇게 시도해본 결과, SNS로 로그인하면 캡챠가 뜨지 않는다는걸 알아냈다.

 

2. 자동 로그인

 

  바로 트위터 계정을 만들고, 로그인하는 코드를 만들어 테스트해보았다.

 

  잘 로그인되는것을 확인했다.

 

  이어서 그랑블루 연동을 시도해보았다.

  로그인은 2단계로 나누어지는데,

  1. ID/PW를 입력하고 로그인버튼을 누르는 과정(혹은 SNS 연동 로그인 버튼을 누르는 과정)

  2. 적합한 로그인 시도였을 경우 로그인 성공 화면이 뜨는데, 여기서 "확인" 버튼까지 누르고 난 이후에야 로그인 처리가 성공적으로 끝난다.

 

  따라서 모바게(그랑블루 서비스 회사) 로그인 페이지에서 트위터 연동 버튼을 눌러 세션을 획득 한 후,

 

  그랑블루 게임으로 찾아가 login버튼을 눌러주었다.

  쉽게 생각하면 넥슨 홈페이지에서 로그인하면 메이플스토리 게임페이지에서도 바로 로그인 할 수 있는것과 비슷하다고 볼 수 있겠다.

 

  + 누르려하는 버튼의 크기가 커 다른 element에 가려지는 에러가 생겨, executeScript로 click함수를 실행해주었다.

  + sendKey(enter)는 키보드로 입력 가능한 버튼이 아니었는지 작동하지 않았다.

 

  새 탭에서 로그인 확인 창이 실행되므로, 다른 탭으로 전환해준후(어짜피 탭은 단 두개뿐) 확인버튼을 눌러 종료했다.

 

  그렇게 사람 손 없이 코드만으로 로그인하는데 성공할 수 있었다.

 

  최종 코드만 올려놓으니 별 거 없긴한데, 온갖 에러 검색해보며 여기까지 오는데 이틀정도 걸린것같다...

 

1. 프로필 페이지 크롤링

 

  우선 그랑블루 프로필 페이지의 규칙을 살펴봐야 한다.

부계정 no.4

  위 사진처럼 모든 계정들은 ID라는 고유번호를 가진다.

  반드시 8자리인건 아니고, 계정 생성에 따라 증가하는 번호이다.(이유는 모르겠으나 정확히 1씩 증가하지는 않는다)

 

프로필 주소

  그리고 프로필페이지 주소는 보다시피 /#profile/고유번호 로 접근 가능하다.

  

  그럼 간단하게 url로 요청을 보내서, html 문서를 얻고, 이름/랭크 등 필요한 정보를 id/class/tag로 추출하면 끝나는거 아닌가? 와 프로젝트 끝!

 

간단!

  그렇게 생각하고 아주 간단한 테스트 페이지를 만들어 보았다.

명료!

  버튼을 누르면 하드코딩된 URL로 프로필 페이지 연결, HTML정보를 얻고 txt-group1이라는 class를 찾아 class명을 출력하는 테스트이다.(txt-group1이란 위에서 언급한 계정 고유 ID이다)

  Jsoup은 HTML문서의 파싱이 가능하게 해주는 라이브러리이다.

행복회로(불탐)

  그렇게 쉬울리가 없었다.

 

게임엔 로딩이 있다.

  왜 Null이 잡혔는가..하니 페이지 전환 사이의 로딩화면이 문제였다.

  게임이니만큼 데이터 로딩은 필요한데, 데이터 로딩 중엔 로딩창을 띄워주고, 데이터 로딩이 완료되면 해당하는 페이지를 보여주도록 되있는 듯 했다.

  그리고 Jsoup는 connect하자마자 받은 그 로딩창의 html을 좋다고 받아왔고, 로딩창에서 있지도 않은 데이터를 찾으려 하니 당연히 Null을 뱉은것.

 

  그러면 Jsoup을 잘 조작해서 로딩 이후의 페이지를 받아올 수 있는가? 구글신에게 문의해 보도록 하자

  JSoup는 그냥 HTML만 받아올 뿐, 어림도 없는 소리였다.

 

 

2. 셀레니움 설치

 

  하지만 착한 스택-오버플로우 사람들이 다른 방법을 남겨 주었다 (링크)

  selenium이라는 라이브러리로 동적으로 추가되는 요소들에도 접근 가능하다는 것.

  정확히는 요소 상태를 감시하다 등장한 이후에 페이지를 긁으면 된다고 한다.

 

  그렇게 셀레니움 설치부터 다시 시작하게 되었다

 

  블로그 글이 죄다 add external jar로 추가하던데, 프로젝트 그대로 다른 환경에서도 돌려보고 싶으므로 내부에 직접 추가했다. 8Mb정도는..괜찮지 않을까?

 

셀레니움 init

  사용하기 위한 크로미움 드라이버 또한 현재 크롬 버전에 맞춰 설치했다 (링크)

목표 elements가 보일 때까지 대기하는 코드(상상도)

  그렇게 실행해 본 결과

짜잔

  셀레니움은 새로운 브라우저를 키는것처럼 작동하는 방식이라는 걸 알게되었고,

  이 브라우저는 시크릿모드와 같아 로그인 세션같은건 하나도 남아있지 않다는 걸 알게되었다.

 

  그럼 그 로그인부터 하면 되지 않을까?

캡챠

  

  오늘의 2번째 어림도 없는 소리였다.

 

  캡챠를 프로그램으로 뚫을수 있는 방법이 있나....?

  아무튼 오늘은 머리아파졌으므로 그만하기로 했다.

* 이 프로젝트는 흥미위주의 토이프로젝트로, 상업적 목적을 가지지 않습니다.

 

0. 개요

 

  지난 수속 고전장때문에 장어 친구를 구하고.. 끝난다음 티탄 아니면 자르고..를 반복하다 문득 이런 생각이 들었다

 

  "유저들의 소환석 정보를 가져다 저장해두고 내가 원하는 세팅의 유저를 찾아서 친구추가 할 수 있으면 좋지 않을까?"

 

  하지만 이용약관, 저작권법 등에 위반되는건 무서우므로, 확인해보기로 했다.

 

 

1. 저작권 관련

 

그랑블루 판타지 사이트 이용 약관(영문)

  약관치곤 너무 짧아 이상하긴한데, 신규 계정을 만들어봐도 동의를 구하는 이용약관같은게 보이지 않았다.

  

  어쨋든 위 이용 약관의 Copyright부분을 확인하면, 저작권법에 의한 사적 사용에 대해서는 사용 가능하다는 항목이 존재한다.

 

  그랑블루는 일본게임이므로 일본의 저작권법을 확인해 볼 필요가 있다.

  하지만 나는 일알못이고, 번역기를 돌려서 법령을 확인할 수는 없는 노릇이므로, 한국저작권위원회의 번역된 일본 저작권법을 참고하였다 (링크)

  

일본 저작권법 30조 (사적사용을 위한 복제)

 

  저작권법 30조에 명시되어 있듯 사적사용이란 개인적으로 / 가정에 준하는 한정된 범위 내에서 사용할 경우를 말하며, 이 경우 복제 및 사용이 가능하다고 되어 있다.

  예외 조항을 확인해보면,

  •   1. 공공사용목적의 자동복제기기를 이용 : 아니다
  •   2. 기술적 보호수단의 회피 목적 : 웹 페이지로 접근하는 방식이므로 해당하지 않는다

언급된 2조 1항 20호, 특정한 반응/변환을 하토록 가공된 정보를 말하는 것으로 해석했다.

  •   3. 자동공중송신..이 뭔지 모르겠어서 다시 한국저작권위원회를 참고해보았다.

  '복제물을 여러 사람에게 제공할 소지'로 미루어보면 저작물을 특정인/집단이 아닌 공공에 송신하는 행위를 말하는게 아닐까 생각했다.

  실제 판례로 'TV 프로그램을 인터넷으로 방송하던 업체에 대한 방송사의 소송'을 찾을 수 있었다.(PDF링크)

  정보를 뿌리고 다닐건 아니므로 해당하지 않는다고 판단했다.

 

 

2. 크롤링(스크래핑) 관련

 

  아무래도 웹 게임이다보니 모든 화면이 곧 웹 페이지다.

  즉 페이지 스크래핑을 해야 정보를 얻을수 있다는 뜻이 된다.

 

robot.txt, robots.txt, robot/robot.txt 등 전부 404

  그러므로 일단 규약을 확인하러 robots.txt를 확인해보려 했는데 찾을수가 없다.

 

있었는데요

 

  혹시 root 도메인이 다른게 아닐까 찾아보니 game.이 빠진 도메인에 robots.txt가 있다고 잡힌다 (링크)

 

없었습니다

  그런데..없었습니다.

  

  애초에 의무사항은 아니라지만.. 운영약관에도 robots.txt에도 관련 내용을 찾을 수 없어져버렸다.

 

  뭔가 검색을 더 해보니 이런 글(링크)이 보여서, 이 내용들을 지키면서 실행해 보기로 했다.

 

  

  추후 저작권이나 약관 관련 위반 사실을 알게되면, 그때 폐기하거나 수정하거나 하는걸로..

 

 

 

  현실에도 게임에도 친구찾기는 참 어렵다

 

+ Recent posts