조회 수 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
    앗 답변 감사합니다 :)
    이니스프리님도 새해 복 많이 받으세여 !

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
38 코드 파이선 셸에서 실행하면...? 3 제르엘 2018.07.22 634
37 코드 [Python] 모 정부기관 사이트 파싱 후 PC 통신처럼 열람하고 싶은 게시글 번호를 입력하면 내용을 보여주는 소스 (허접) 4 이니스프리 2018.09.14 755
36 코드 [오토핫키] 특정 사이트에 대한 ping 테스트 결과를 실행시간과 함께 로그 파일로 저장하는 스크립트 2 이니스프리 2018.09.22 2102
35 코드 [오토핫키] 구글 드라이브의 공유링크를 이미지 호스팅을 위한 다이렉트 링크로 바꿔주는 스크립트 10 file 이니스프리 2018.09.25 1784
34 코드 [PHP] 기상청 중기예보를 캐러셀로 보여주는 위젯 (매우 허접합니다 ㅠㅠ) 10 file 이니스프리 2018.09.28 756
33 코드 [오토핫키] 브라우저를 열어 지난번과 동일한 폴더에 MZK를 다운받고 압축을 네이티브로 해제하는 스크립트 file 이니스프리 2018.10.20 928
32 코드 [PHP] 기상청 RSS 시간별 예보 위젯 - cache 적용(?) 9 file 이니스프리 2018.10.28 1003
31 코드 [PHP] 그누보드 자동 게시글 작성 - 일본기상협회의 우리나라 날씨를 크롤링한 후 파파고로 번역하여 글 작성 4 file 이니스프리 2018.11.15 844
30 코드 [아미나] 게시글을 작성하면 ID와 IP로 필터링하여 자동으로 랜덤 댓글을 남기기 (+랜덤 포인트) 7 file 이니스프리 2018.11.18 814
29 코드 [Python] 텔레그램을 이용한 게시판 새 글 알림봇 7 이니스프리 2018.12.02 4030
28 코드 [PHP] 간단한 캐싱 클래스 3 title: 황금 서버 (30일)humit 2018.12.06 882
27 코드 [아미나] 출석 여부를 나타내는 메인화면 위젯 4 file 이니스프리 2018.12.15 811
26 코드 [아미나] 네이트 실시간 검색어 순위 위젯 (아미나 캐시 적용) 3 file 이니스프리 2018.12.18 1134
25 코드 [PHP] 이미지를 원하는 크기(원본비율 유지)로 리사이즈 하여 출력 (원본 이미지는 수정하지 않습니다) 6 이니스프리 2018.12.20 8016
24 코드 [JS] http를 https로 리디렉션! 3 Hanam09 2018.12.30 885
23 코드 [JS]클라이언트에서 Ip를 얻어보자 2 Hanam09 2019.01.21 807
22 코드 [Python] 선택한 파일을 Dropbox API를 이용하여 업로드하고 공유링크를 받아서 이미지 호스팅 용도로 URL을 변환하기 1 file 이니스프리 2019.07.02 1192
21 코드 [Python] Selenium을 이용하여 특정 element를 캡처하는 스크립트 2 file 이니스프리 2019.07.03 6170
20 코드 [PHP/Javascript] 아미나에 자동으로 게시글을 생성하고 Ajax로 전송하여 결과를 표시하기 2 file 이니스프리 2019.07.09 963
19 코드 [Python] 네이버 모바일 이미지 검색에서의 이미지 파일을 멀티스레드로 다운받고 1개의 파일로 병합 11 file 이니스프리 2019.07.12 1557
Board Pagination Prev 1 2 3 4 Next
/ 4