콘텐츠로 건너뛰기

스마트스토어 자동 프로그램 만들기

  • by
  • 2022년 6월 18일2022년 6월 18일

현재 스마트스토어 자동화 시스템을 만들어서 자동화 수익을 만들어놓았습니다.

2022년 6월 15일 인터넷익스플로러 지원을 중단하면서 더이상 익스플로러 브라우저로 네이버에 접속을 할 수 없게되었습니다.

그로인해 3년전에 만들어놓았던 인터넷 익스플로러 기반의 자동 프로그램을 업데이틀 해야 할 시기가 되버렸습니다.

 

스마트스토어 자동 프로그램 만들기 – 로그인편

오늘은 로그인만 간단하게 C#을 이용해서 만들어보도록 하겠습니다.

그리 어렵지는 않고 원리만 알면 쉽습니다.

 

일단 스마트스토어 로그인 페이지에는 아주 멋진 웹 기술이 포함되어져있습니다.

두가지가 있는데요.

한가지는 로그인을 기계적으로 하지 못하도록 막는 기술이 있습니다.

또 다른 한가지는 로그인을 기계가 하는것을 막는 기술입니다.

둘다 같은 말이기는 하지만 서로 다른 기술이라서 이렇게 표현했습니다.

 

제일 먼저 로그인창을 만들어야지만 로그인 이후에 주문 상품 리스트를 가져올 수 있습니다..

비밀번호란을 잘 보시면 암호가 등록되어져있지만 ※ 필수 정보입니다. 라는 문구가 나옵니다.

다른 한가지는 캡챠인데… 로그인 실패할때 보통 나오는 자동방지 알고리즘이라서 오늘은 그까지 볼 기회가 없어보입니다.

캡챠 뜨더라도 로그인 할 수 있는 방법 많으니 너무 걱정하지마시고요.

 

아래 GIF 움짤을 잘 보세요.

분명 암호가 이미 등록되어져있었는데 제가 클릭하여 글자 하나를 쳐주니 필수정보 항목이 사라졌죠?

 

너무 쉽게 해결이 되버렸습니다.

아이디 등록은 document.getElementById(“loginId”).value = “로그인 아이디” 등록하시면 됩니다.

비밀번호 등록은 document.getElementById(“loginPassword”).value = “암호” 등록하시면 됩니다.

이까지는 쉽습니다. 버튼만 누르면 아이디 암호가 등록되도록 했으니깐요.

 

하지만 실제로 사람처럼 마우스로 한번 클릭해서 글자를 눌러주어야지만

네이버 고급 자바스크립트 스킬을 피할 수 있습니다.

이때 방법이 다양합니다.

그냥 로그인 할 때마다 귀찮더라도 띵똥 소리 나게 해서 직접 치는 방법도 있고요.

(이방법 장난처럼 느끼실수 있으나… 프로그래머들 사이에서 실제로 어쩔수 없는 상황에는 이렇게도 만들어야 합니다)

또 다른 방법은 매크로로 간단하게 마우스 이동해서 글자 쳐눌러주는겁니다.

하지만 우리는 C#으로 하고 싶으니 그러한 기능의 윈도우32 함수를 찾아서 사용하면됩니다..

 

MouseClick 함수와 KeyboardPress 함수를 이용하면됩니다.

우선 제일 상단에 함수부터 선언해줍니다.

 

[DllImport("user32.dll")]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
[DllImport("user32.dll")]
static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInf);


private const uint MOUSEMOVE = 0x0001; // 마우스 이동

private const uint LBUTTONDOWN = 0x0002; // 왼쪽 마우스 버튼 눌림
private const uint LBUTTONUP = 0x0004; // 왼쪽 마우스 버튼 떼어짐

private const uint RBUTTONDOWN = 0x0008; // 오른쪽 마우스 버튼 눌림
private const uint RBUTTONUP = 0x00010; // 오른쪽 마우스 버튼 떼어짐

private const uint ABSOLUTEMOVE = 0x8000; // 전역 위치


private const byte VK_SPACE = 0x20;
private const byte VK_RETURN = 0x0D;
private const byte VK_BACKSPACE = 0x08;
private const byte VK_TAB = 0x09;
private const byte VK_PRIOR = 0x21;

private const byte KEYEVENTF_EXTENDEDKEY = 0x0001;
private const byte KEYEVENTF_KEYUP = 0x0002;





private void KeyboardPress(byte keyCode)
{
keybd_event(keyCode, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);

//keybd_event(keyCode, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0);
//keybd_event(keyCode, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}

private void MouseClick(bool isClick, Point point, uint width, uint height)
{
Rectangle rtScreen = Screen.PrimaryScreen.Bounds;

uint nX = (uint)(65535 * (point.X + width) / rtScreen.Width);
uint nY = (uint)(65535 * (point.Y + height)/ rtScreen.Height);

if (isClick)
{
mouse_event(ABSOLUTEMOVE | MOUSEMOVE | LBUTTONDOWN, nX, nY, 0, 0);
mouse_event(ABSOLUTEMOVE | MOUSEMOVE | LBUTTONUP, nX, nY, 0, 0);
}
else
{
mouse_event(ABSOLUTEMOVE | MOUSEMOVE, nX, nY, 0, 0);
}


}
그리고 아래의 내용을 사용하면 됩니다.

IWebElement id = driver.FindElement(By.Id("loginId"));
id.Clear();

Point position = id.Location;

id.SendKeys(textBox_아이디.Text);
MouseClick(true, position, 350, 160);

KeyboardPress(VK_BACKSPACE);

Thread.Sleep(100);
IWebElement pw = driver.FindElement(By.Id("loginPassword"));
pw.Clear();
pw.SendKeys(textBox_비밀번호.Text);

Thread.Sleep(100);

MouseClick(true, position, 350, 200);
KeyboardPress(VK_BACKSPACE);

Thread.Sleep(100);

//로그인버튼
MouseClick(true, position, 350, 280);

 

마우스 포지션을 우선 알아야 하므로 Label 을 하나 만들어서 마우스가 이동할때마다 포인트를 x,y 나오도록 하였습니다.

그리고 로그인 영역에 마우스를 날려야 하므로 Button 을 3개 만들었습니다.

버튼을 만든 이유는 그 위치로 마우스포인트를 옮기기 위해서입니다.

직접 Location 정보를 입력하면 가장 좋지만…

실제로 프로그램을 실행하다보면 위치를 찾기가 어려울때가 있습니다.

이를 대비해서 패널이나 버튼을 올려서 위치를 찾습니다.

 

 private void getMouthLocation()
{
label_XY.Text = String.Format("{0},{1}", MousePosition.X - this.Location.X, MousePosition.Y - this.Location.Y);
}


private void panel_MouseMove(object sender, MouseEventArgs e)
{
Button button = sender as Button;
ReleaseCapture();
SendMessage(button.Handle, SYSTEMCOMMAND, SC_DRAGMOVE, 0);


//button_포커스키워드
WriteValue(button.Name, "X", button.Left.ToString());
WriteValue(button.Name, "Y", button.Top.ToString());

getMouthLocation();
}

 

위의 두 소스를 이용하면 좌표를 알 수 있으며 버튼을 프로그램 안에서 움직이도록 드래그 할 수 있습니다.

버튼에 Mousemove() 함수를 연결 시키면 됩니다.

 

이제 남은 부분은 버튼을 옮겨놓고 그위에 고정시키는 것과

버튼의 location.X와 location.Y를 찾아내어서 왼쪽 -1, -1 영역을 클릭 하고 글자를 하나 써주기만 하면됩니다.

저는 이 부부분을 조금 더 쉽게 하기 위해서 글자를 미리 한글자 더 쳐넣고 글자를 지우는 방식으로 처리했습니다.

 

[DllImport("kernel32")]
private static extern long WritePrivateProfileString(String section, String key, String val, String filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(String section, String key, String def, StringBuilder retVal, int size, String filePath);


public string PATH = string.Format("{0}/{1}.ini", System.AppDomain.CurrentDomain.BaseDirectory, Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyTitleAttribute>().Title);


public void WriteValue(String strSection, String strKey, String strValue)
{
WritePrivateProfileString(strSection, strKey, strValue, PATH);
}

public void DeleteSection(String strSection)
{
WritePrivateProfileString(strSection, null, null, PATH);
}

public string ReadValue(String strSection, String Key)
{
StringBuilder strValue = new StringBuilder(255);
int i = GetPrivateProfileString(strSection, Key, "", strValue, 255, PATH);
return strValue.ToString();
}

 

위의 소스코드는 특정 위치를 저장하기 위한 코드입니다.

아까 마우스 이동 소스를 잘 보면 그안에 위치를 저장하는 코드가 있습니다.

private void panel_MouseMove(object sender, MouseEventArgs e)
{
Button button = sender as Button;
ReleaseCapture();
SendMessage(button.Handle, SYSTEMCOMMAND, SC_DRAGMOVE, 0);


//button_포커스키워드
WriteValue(button.Name, "X", button.Left.ToString());
WriteValue(button.Name, "Y", button.Top.ToString());

getMouthLocation();
}

 

그리고 프로그램을 처음 호출할때 저장 해놓은 파일을 불러와서 위치를 기억해서 옮기면 됩니다.

if (ReadValue(button_포커스_로그인_아이디.Name, "X") != "")
{
button_포커스_로그인_아이디.Location = new Point(Int32.Parse(ReadValue(button_포커스_로그인_아이디.Name, "X")), Int32.Parse(ReadValue(button_포커스_로그인_아이디.Name, "Y")));
}


if (ReadValue(button_포커스_로그인_암호.Name, "X") != "")
{
button_포커스_로그인_암호.Location = new Point(Int32.Parse(ReadValue(button_포커스_로그인_암호.Name, "X")), Int32.Parse(ReadValue(button_포커스_로그인_암호.Name, "Y")));
}


if (ReadValue(button_포커스_로그인_로그인버튼.Name, "X") != "")
{
button_포커스_로그인_로그인버튼.Location = new Point(Int32.Parse(ReadValue(button_포커스_로그인_로그인버튼.Name, "X")), Int32.Parse(ReadValue(button_포커스_로그인_로그인버튼.Name, "Y")));
}

 

이렇게 처음 한번만 실행하면 마우스로 이동시킨 버튼의 위치를 자동으로 저장할 수 있습니다.

이제 남은 숙제인 마우스로 포인트를 옮기고 클릭하여 그곳에 글자를 하나 써주기만 하면됩니다.

 

button_포커스_로그인_아이디.Visible = false;
button_포커스_로그인_암호.Visible = false;
button_포커스_로그인_로그인버튼.Visible = false;

Thread.Sleep(1000);

webView21_스마트스토어?.CoreWebView2.ExecuteScriptAsync("document.getElementById('loginId').value='" + textBox_아이디.Text + "'");

Cursor.Position = new Point(button_포커스_로그인_아이디.Location.X, button_포커스_로그인_아이디.Location.Y);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);

Thread.Sleep(100);
KeyboardPress(VK_BACKSPACE);

webView21_스마트스토어?.CoreWebView2.ExecuteScriptAsync("document.getElementById('loginPassword').value='" + textBox_비밀번호.Text + "'");


Cursor.Position = new Point(button_포커스_로그인_암호.Location.X, button_포커스_로그인_암호.Location.Y);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);

Thread.Sleep(150);
KeyboardPress(VK_BACKSPACE);


Thread.Sleep(550);

Cursor.Position = new Point(button_포커스_로그인_로그인버튼.Location.X, button_포커스_로그인_로그인버튼.Location.Y);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);

이제 네이버 스마트스토어 로그인은 자동으로 해결 되었습니다.

로그인이 잘 되었습니다. 축하합니다!! 

다음 단계는? 주문페이지에서 주문리스트를 가져와야겠죠?

주문페이지에서 주문리스트 가져오는것은 더 쉽습니다. 로그인에 비하면 훨씬 쉽죠.