조회 수 3590 추천 수 0 댓글 9
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
Extra Form
라이선스 MIT

안녕하세요?

 

어제 모처럼 시간이 나서 헬스장에 가려고 했으나 

 

낙뢰 때문에 부득이 헬스장에 못 가고 이 소스를 짰습니다.

 

전 세계에서 해마다 놀이기구를 타다가 사망하는 사람보다 

 

낙뢰에 의해 사망하는 사람이 더 많다고 들었습니다 ㅎㄷㄷ

(운동 안 하기에 아주 좋은 핑계네요 ㅠㅠ)

 

 

이 스크립트는 새 글 작성시 CMS에서 새 글 표시가 달리는 것을 이용해서 

 

해당 게시글에 자동으로 댓글을 다는 목적으로 제작되었습니다.

 

커뮤니티를 제작하면 초기에는 무플 방지가 필요하다고 생각되어서요 ㅠㅠ

(커뮤니티를 제작하기도 전에 벌써부터 무플 걱정을 하다니 ㅜㅜ)

 

물론 PHP로도 구현할 수 있겠지만

 

CMS와 무관하게 돌아가는 소스를 짜고 싶었습니다.

(실은 제가 어떤 CMS로 커뮤니티를 만들지 아직 정하지 못했거든요 ㅠㅠ)

 

 

이 스크립트는 Autohotkey_L을 기준으로 제작되었고

 

브라우저나 CMS를 가리지 않고 사용할 수 있습니다.

 

다만 마우스 좌표 기반이다보니 부정확한 경우가 있어서

 

중복으로 댓글이 달리는 것을 방지하기 위해

 

마우스 클릭 후 URL이 바뀌는지 여부를 수시로 체크합니다.

 

 

만약 커뮤니티에 새 글 아이콘을 24시간 달리도록 설정하셨다면 

 

윈도우 스케쥴러에서 24시간마다 작동하게 하면 자동으로 돌아갑니다.

 

 

다음 몇 가지를 셋팅하셔야 됩니다.

 

1. new.bmp 파일

 

새 글 작성시 달리는 새 글 표시 아이콘을 new.bmp로 저장합니다.

 

캡쳐하셔도 돌아갑니다.

 

다만 오토핫키의 특성상 bmp나 png 파일은 잘 분석하지만 

 

gif나 jpg 파일은 제대로 작동하지 않을 가능성이 큽니다.

(사실 대부분의 아이콘은 gif나 jpg 파일이죠 ㅠㅠ)

 

그리고 브라우저를 100% 비율로 놓고 사용하지 않으면 캡쳐햐셔야 됩니다 ㅠㅠ

 

 

2. reply.bmp

 

리플 버튼을 캡쳐해서 reply.bmp로 저장합니다.

 

상당수의 커뮤니티에서 리플 버튼이 이미지 파일로 존재하지는 않을테니

 

이건 캡쳐하셔야 될 것 같습니다.

 

 

3. longtime 변수값

 

longtime 변수는 커뮤니티 클릭 후 로딩에 걸리는 시간에 따라 적정한 값을 입력하시면 됩니다.

 

단위는 ms입니다.

 

국내의 무난한 웹호스팅이라면 3000, 벌쳐나 리노드라면 5000, 

 

그리고 테스트 해보지 않았지만 미국이나 호주 서버는 넉넉히 7000 정도 잡으시면 될 것 같습니다.

 

 

4. mention 변수값

 

리플로 남기고 싶은 문구를 mention1~15 변수에 입력하시면 

 

루프가 돌아가면서 순서대로 해당 문구를 리플로 남깁니다.

 

물론 15개 이상 지정하셔도 무방합니다.

 

 

5. PgUP & PgDN

 

이건 화면 해상도에 따라서 달라질 수 있는 부분이네요.

 

new 아이콘과 댓글쓰기 버튼이 화면에 출력될 수 있도록

 

페이지 업과 다운 횟수를 적절히 조절하시면 됩니다.

 

 

6. 크롬 이외의 브라우저

 

이 소스는 모든 브라우저에서 작동하도록 제작되었으며

 

chrome.exe 부분을 변경하면 다른 브라우저에서도 작동하는 것을 확인했습니다.

 

 

첨언하자면 getactiveURL 함수는 오토핫키 공식포럼에 오픈된 소스를 사용하였습니다. 

 

출처는 다음과 같습니다. (atnbueno 님 작성)

 

https://autohotkey.com/boards/viewtopic.php?t=3702

 

사실 크롬에서만 작동하게 하려면 send ^l와 send ^C를 이용해서

 

불과 몇 줄로 간단하게 작성할 수도 있지만 

 

범용으로 제작하다보니 상당히 긴 길이의 함수를 사용하게 되었네요 ㅠㅠ

 

 

제가 크롬, IE, 파폭 등 브라우저에서 돌아가는 것을 확인하였지만 

 

급히 만들다보니 소스에 여러 군더더기가 있습니다. 

 

특히 while 문의 첫번째 루프 돌리는 부분을 더 깔끔하게 만들었어야 했는데 말이죠.

 

군더더기나 부족한 부분이 있으면 스포어의 회원님들께서 지적해주시면 감사하겠습니다. 

 

 

마지막으로 이 소스를 조금 수정하면 게시판 도배 등에 악용될 수도 있을테니 

 

부디 좋은 목적으로만 사용해주셨으면 합니다 ㅠㅠ

 

그럼 편안한 저녁 되시고 여러모로 부족한 제게 많은 가르침을 주시는 스포어 회원 분들께 항상 감사드립니다.

 

 

longtime = 6000
times = 0
 
mention1 =
mention2 =
mention3 =
mention4 =
mention5 =
mention6 =
mention7 =
mention8 =
mention9 =
mention10 =
mention11 =
mention12 =
mention13 =
mention14 =
mention15 =
 
ModernBrowsers := "ApplicationFrameWindow,Chrome_WidgetWin_0,Chrome_WidgetWin_1,Maxthon3Cls_MainFrm,MozillaWindowClass,Slimjet_WidgetWin_1"
LegacyBrowsers := "IEFrame,OperaWindowClass"
longtime = 6000
 
Run, Chrome.exe "www.google.com"
sleep, 3000
 
ret:=IME_CHECK("Google")
If %ret% <> 0
{
Send,{vk15sc138}
}
 
 
Run, Chrome.exe "URL"
sleep %longtime%
SendInput, {Home}
sleep 2000
SendInput, {PgDn}
sleep 2000
 
sURL := GetActiveBrowserURL()
sleep 1500
sURL1 := sURL
 
 
Imagesearch, vx, vy, 500, 0, 1700, 1200, *80 new.bmp
 
 
 
While (Errorlevel=0) ; The Loop
{
SendInput, {Home}
sleep 2000
SendInput, {PgDn}
sleep 2000
 
times := times + 1
If (times > 1)
{
vylimit := vy + 20
}
If (times = 1)
{
vylimit := vy - 20
}

Imagesearch, vx, vy, 500, %vylimit%, 1700, 1200, *80 new.bmp
sleep 200
 
If (Errorlevel = 0)
{
sleep 200
vx1 := vx - 60
vy1 := vy + 10
sleep 200
Mouseclick, Left, %vx1%, %vy1%
sleep, %longtime%
SendInput, {END}
sleep, 2000
SendInput, {PgUp}
sleep, 2000
SendInput, {PgUp}
sleep, 2000
 
 
sURL := GetActiveBrowserURL()
sleep 1500
If (sURL1 = sURL)
{
Break
}

 
 
 
Imagesearch wx, wy, 800, 0, 1920, 1200, *90 reply.bmp
sleep 200
If (Errorlevel = 0)
{
wx1 := wx + 20
wx2 := wx - 100
wy1 := wy + 20
Mouseclick, Left, %wx2%, %wy1%
SendInput, % mention%times%
sleep 200
Mouseclick, Left, %wx1%, %wy1%
sleep, %longtime%
}
}
 
If (Errorlevel > 0)
{
break
}
 
sURL1 := sURL
sleep 200
Run, chrome.exe "URL"
sleep, %longtime%
}
 
Return
 
 
 
 
; funtion
 
 
GetActiveBrowserURL() {
global ModernBrowsers, LegacyBrowsers
WinGetClass, sClass, A
If sClass In % ModernBrowsers
Return GetBrowserURL_ACC(sClass)
Else If sClass In % LegacyBrowsers
Return GetBrowserURL_DDE(sClass) ; empty string if DDE not supported (or not a browser)
Else
Return ""
}
 
; "GetBrowserURL_DDE" adapted from DDE code by Sean, (AHK_L version by maraskan_user)
; Found at http://autohotkey.com/board/topic/17633-/?p=434518
 
GetBrowserURL_DDE(sClass) {
WinGet, sServer, ProcessName, % "ahk_class " sClass
StringTrimRight, sServer, sServer, 4
iCodePage := A_IsUnicode ? 0x04B0 : 0x03EC ; 0x04B0 = CP_WINUNICODE, 0x03EC = CP_WINANSI
DllCall("DdeInitialize", "UPtrP", idInst, "Uint", 0, "Uint", 0, "Uint", 0)
hServer := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", sServer, "int", iCodePage)
hTopic := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "WWW_GetWindowInfo", "int", iCodePage)
hItem := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "0xFFFFFFFF", "int", iCodePage)
hConv := DllCall("DdeConnect", "UPtr", idInst, "UPtr", hServer, "UPtr", hTopic, "Uint", 0)
hData := DllCall("DdeClientTransaction", "Uint", 0, "Uint", 0, "UPtr", hConv, "UPtr", hItem, "UInt", 1, "Uint", 0x20B0, "Uint", 10000, "UPtrP", nResult) ; 0x20B0 = XTYP_REQUEST, 10000 = 10s timeout
sData := DllCall("DdeAccessData", "Uint", hData, "Uint", 0, "Str")
DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hServer)
DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hTopic)
DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hItem)
DllCall("DdeUnaccessData", "UPtr", hData)
DllCall("DdeFreeDataHandle", "UPtr", hData)
DllCall("DdeDisconnect", "UPtr", hConv)
DllCall("DdeUninitialize", "UPtr", idInst)
csvWindowInfo := StrGet(&sData, "CP0")
StringSplit, sWindowInfo, csvWindowInfo, `" ;"; comment to avoid a syntax highlighting issue in autohotkey.com/boards
Return sWindowInfo2
}
 
GetBrowserURL_ACC(sClass) {
global nWindow, accAddressBar
If (nWindow != WinExist("ahk_class " sClass)) ; reuses accAddressBar if it's the same window
{
nWindow := WinExist("ahk_class " sClass)
accAddressBar := GetAddressBar(Acc_ObjectFromWindow(nWindow))
}
Try sURL := accAddressBar.accValue(0)
If (sURL == "") {
WinGet, nWindows, List, % "ahk_class " sClass ; In case of a nested browser window as in the old CoolNovo (TO DO: check if still needed)
If (nWindows > 1) {
accAddressBar := GetAddressBar(Acc_ObjectFromWindow(nWindows2))
Try sURL := accAddressBar.accValue(0)
}
}
If ((sURL != "") and (SubStr(sURL, 1, 4) != "http")) ; Modern browsers omit "http://"
sURL := "http://" sURL
If (sURL == "")
nWindow := -1 ; Don't remember the window if there is no URL
Return sURL
}
 
; "GetAddressBar" based in code by uname
; Found at http://autohotkey.com/board/topic/103178-/?p=637687
 
GetAddressBar(accObj) {
Try If ((accObj.accRole(0) == 42) and IsURL(accObj.accValue(0)))
Return accObj
Try If ((accObj.accRole(0) == 42) and IsURL("http://" accObj.accValue(0))) ; Modern browsers omit "http://"
Return accObj
For nChild, accChild in Acc_Children(accObj)
If IsObject(accAddressBar := GetAddressBar(accChild))
Return accAddressBar
}
 
IsURL(sURL) {
Return RegExMatch(sURL, "^(?<Protocol>https?|ftp)://(?<Domain>(?:[\w-]+\.)+\w\w+)(?::(?<Port>\d+))?/?(?<Path>(?:[^:/?# ]*/?)+)(?:\?(?<Query>[^#]+)?)?(?:\#(?<Hash>.+)?)?$")
}
 
; The code below is part of the Acc.ahk Standard Library by Sean (updated by jethrow)
; Found at http://autohotkey.com/board/topic/77303-/?p=491516
 
Acc_Init()
{
static h
If Not h
h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromWindow(hWnd, idObject = 0)
{
Acc_Init()
If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
Return ComObjEnwrap(9,pacc,1)
}
Acc_Query(Acc) {
Try Return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Children(Acc) {
If ComObjType(Acc,"Name") != "IAccessible"
ErrorLevel := "Invalid IAccessible Object"
Else {
Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
If DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
Loop %cChildren%
i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
Return Children.MaxIndex()?Children:
} Else
ErrorLevel := "AccessibleChildren DllCall Failed"
}
}
 
 
 
 
 
 
IME_CHECK(WinTitle)
{
WinGet,hWnd,ID,%WinTitle%
Return Send_ImeControl(ImmGetDefaultIMEWnd(hWnd),0x005,"")
}
 
 
Send_ImeControl(DefaultIMEWnd, wParam, lParam)
{
DetectSave := A_DetectHiddenWindows
DetectHiddenWindows,ON
SendMessage 0x283, wParam,lParam,,ahk_id %DefaultIMEWnd%
if (DetectSave <> A_DetectHiddenWindows)
DetectHiddenWindows,%DetectSave%
return ErrorLevel
}
 
 
ImmGetDefaultIMEWnd(hWnd)
{
return DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hWnd, Uint)
}
 

 

  • profile
    NoYeah 2017.11.27 11:07
    괜찮은 자료군요!

    라이믹스는 애드온이 있어서 자동으로 댓글달리게 하는 것도 있습니다!
  • profile
    이니스프리 2017.11.27 11:21
    앗 그렇게 말씀해주셔서 감사합니다!

    어제 밤에 이거 올리고 다시 한 번 확인하려고 돌려봤는데

    아무래도 imagesearch 명령어를 사용하다보니 100% 완벽하지는 않고

    솔직히 여러모로 허접하더군요 ㅠㅠ

    저도 다음에는 꼭 라이믹스로 갈아타서 자동 댓글 애드온도 사용하고

    아플로스 스킨도 사용해봐야겠네요 ^^

    그럼 맛스타 님께서도 점심식사 맛있게 드세요~
  • profile
    title: 황금 서버 (30일)humit 2017.11.27 18:57
    오토 핫키가 생각보다 많이 복잡하네요 ㅠㅠ...
  • profile
    이니스프리 2017.11.27 20:55

    앗 제가 작성한 부분은 주로 imagesearch와 mouseclick 명령어를 이용한 간단한 while 문이구요

    브라우저를 불문하고 URL을 확인하는 함수 부분(인용한 부분)이 복잡하더군요 ㅠㅠ

    솔직히 저도 그 함수 부분은 다 이해하지 못하고 나머지 부분을 작성했어요 ㅜㅜ

    본문에서도 말씀드렸지만 크롬에서만 작동하도록 작성하면 저 부분은 몇 줄 정도로 간결해집니다 ^^


    저도 오토핫키를 화면과 마우스 조작 위주로 살짝 접해본 수준이지만

    써드파티앱인 매크로 녹화 프로그램을 이용하면 간단하게 매크로도 만들 수 있고

    엑셀을 직접 조작하는 명령어도 있고

    파이썬에 비할 바는 아니지만 간단한 파싱도 가능하고

    오토핫키의 활용범위가 꽤 넓더군요.

    모레부터 또 추위가 슬슬 다가온다는데 그럼 humit 님께서도 감기 조심하시고 항상 건강하세요!

  • profile
    네모 2017.11.29 22:12
    제가 오토핫키를 사용해보지 못해서... 잘 모르겠습니다만.

    1. 새글 찾는건 오토핫키 내에서 파싱해서 불러오고
    2. 그 글에 댓글 다는건 브라우저에서 댓글 위치까지 갈 수 있는 경로(커서위치 및 스크롤 횟수)를 지정해서 입력 후 Tab키를 눌러 등록버튼 인식

    을 하면 이미지서치를 사용하지 않더라도 모든 브라우저에서...!!
  • profile
    이니스프리 2017.11.29 23:04

    네모 님 말씀에 동감합니다 ^^

    특히 두번째로 말씀하신 것에 대해서 저도 시도해보려고 했는데요.

    커서위치 및 스크롤 횟수나 Tab 키 누르는 횟수 등은 게시판마다 천차만별이더군요 ㅠㅠ

    어떤 게시판은 20번 이상 Tab을 입력해야 되어서

    저같이 어리버리한 사람은 숫자를 세는 것이 힘들었어요 ㅜㅜ

     

    그리고 제가 오토핫키로 파싱을 해본 적이 없어서 솔직히 그 부분은 보류했습니다 T.T



    그리고 엄밀히 모든 게시판에서 위 스크립트가 작동하게 하려면

    Imagesearch에서 Errorlevel=1(이미지 없음)이 나오면

    한 번 더 PgDn 해서 다시 Imagesearch 하도록 반복하는 것이 맞겠지만

    미처 제가 거기까지 스크립트를 짜지는 못 했네요 ㅜㅜ


    그럼 내일부터 토요일까지 춥다고 하던데 네모 님께서도 감기 조심하세요 ^^

    네모 님께 항상 이것저것 많이 배워서 감사드립니다 :)

     

  • ?
    Nerd 2018.02.15 23:42
    좀 늦긴 했지만, 굳이 이미지 인식을 통해서 하는 이유가 무엇인가요??
    winhttp 같은 라이브러리를 이용하면 데이터 파싱 및 전송 이 좀 더 쉬운게 아닐까 생각이 드네요!
    질문에 대한 답변을 해주실 수 있나요?
  • profile
    이니스프리 2018.02.16 11:52
    안녕하세요?
    제가 굳이 이미지서치를 사용하게 된 특별한 이유가 있는 것은 아니구요.
    한 번 오토핫키의 이미지서치를 연습해보고
    어느 정도 정확성 내지 신뢰성이 보장되는지 테스트해보고 싶었습니다 ㅎㅎ
    그리고 말씀하신대로 이미지서치가 우회적인 방법이긴 하지만
    여러 사이트에 빨리 적용하거나 홈페이지 수정 등에 빨리 대응할 수 있는 등 나름대로의 장점도 있다고 생각됩니다 :)
    시간적인 측면을 고려하면 개별 사이트를 파싱하는 것보다는 차라리 매크로 레코딩이 간편할테니깐요.
    그럼 새해 복 많이 받으세요 ^^
  • ?
    Nerd 2018.02.16 15:54
    앗 답변 감사합니다 :)
    이니스프리님도 새해 복 많이 받으세여 !

  1. 세린서버에서 시도중인 백업 스크립트 입니다.

  2. 소셜XE / 기존 통합 로그인 스킨 V2.2

  3. 경험치 현황 위젯

  4. Gentelella

  5. Gentelella 레이아웃에 사용가능한 가격 테이블 위젯입니다.

  6. AdminLTE용 에디터 스타일

  7. 엑셀파일 불러서 히스토그램 그려주는 함수

  8. 엑셀 읽어서 그래프 그려주는 함수

  9. RBGE - 이쁘고 깔끔한 에러페이지

  10. even_move - 감성적인 에러 페이지

  11. [XE / Rhymix] Bootstrap 패널 위젯 스타일

  12. [1.8a] Bootstrap 'Panel' 위젯 스타일

  13. Git 저장소에서 자동으로 받아 업데이트하는 쉘 스크립트

  14. [Bootstrap] xeACE 레이아웃

  15. 링크 파싱 애드온용 스킨 (트위터 스타일)

  16. 이게 팔릴까 - Xe/라이믹스 에러페이지 [2017-10-04]

  17. AdBlock 접근 방지 애드온 v0.1

  18. 브라우저 언어에 따라 다른 폴더를 사용하는 PHP 코드

  19. 파이썬을 이용한 텔레그램 새 글 알림 (허접합니다)

  20. 새 글 자동 댓글 스크립트 (AutoHotkey)

Board Pagination Prev 1 2 3 4 Next
/ 4