저는 Go가 쓴 Statefull의 Virtual Web Browser 라이브러리의 Surf로 자바스크립트를 처리해보고 싶어요.
14864 단어 GoWebKitwebkit2gtk
입문
22일 보도입니다.
늦어서 미안해.
TL; DR;
최선을 다했지만 오투와 웹루프에서는 이루지 못했는데...orz
앞으로도 otto와 webloop 이외의 방법을 시도해 보고 싶습니다.
이번 Advent Calender 구동 개발은 이전에 했던 Go3 Advent Calender를 최신화하고 싶었는데 갑자기 벽에 부딪혔어요.
상기 도구는 Slack에 emoji의 API를 업로드하지 않았기 때문에 emoji를 Slack에 업로드하는 도구라는 가상 브라우저 라이브러리를 사용하여 emoji를 겨우 업로드했지만 Slack의 UI가 업데이트된 후부터 움직이지 않았다.
Slack의 이모지 이전 마이그레이션 업로드
처음에는 단순히 Surf
brower.Click()
로 대화 상자를 열고 입력하면 된다고 생각했어요.하지만 그리 간단하지는 않은데...
Surf의...
실제로 서프의 브라우저의 원본을 보면 http의 Request, Response, Cookie, DOM용 goquery 등 자바스크립트와 관련된 처리를 하지 않은 것 같다.
이거 너무 어려워요.이게 안 되면 원래 하고 싶은 걸 할 수가 없어요.
그래서 저는 Surf가 자바스크립트를 실행하는 기능을 어떻게 갖추어야 하는지에 도전했습니다.
우선 조사
Golang에서 Javascript를 실행할 수 있는 헤더 없는 브라우저가 있는지 조사하다가 Surf의 Click()은 Javascript 이벤트의 발화를 지원하지 않습니다. 이 항목을 발견했습니다.
여기에 다음 두 개의 라이브러리를 소개합니다.
otto
이것은 자바스크립트를 실행하면 결과를 얻을 수 있는 것이지만, 모두 Golang으로 쓰인 대단한 라이브러리입니다.
이렇게 하면 페이지에 있는 자바스크립트만 실행하면 될 것 같은데... 제가 찾아봤는데 자바스크립트 라이브러리를 실행하기 위해서였어요.
하지만 이수 등만 봐도 webloop, DOM 작업을 위해 HTML을 읽을 수 없습니다. 등의 사용법이 가능한 것 같다.
상술한 상황에 따라 이번에는 otto에서 HTML을 제출하여 자바스크립트를 실행하기 어렵다고 판단했습니다.
webloop
Golang에서 웹kit2를 이동하는 go-webkit2의 헤더 없는 브라우저를 사용해서 URL을 읽고 JS를 실행할 수 있다고 합니다. 그러면 하고 싶은 일을 할 수 있습니다.
방법으로 웹loop은 URI에서 원본을 읽는 것이 아니라 HTML을string으로 읽을 수 있기 때문에 Surf에서 필요할 때 HTML을 꺼내서 웹loop으로 자바스크립트를 처리하고 Surf에서 결과를 되돌려주는 절차를 고려했다.
환경 설정
이번에 사용한 것은 (좀 낡았지만) macOS Sierra입니다.
React를 이동할 수 있습니다. 페이지를 보고 설치하는 데 필요한 의존 관계입니다.
페이지의 일부 JavaScript를 이동하여 필요한 정보를 얻습니다.를 보고 맥의 경우 아래 명령을 발행하면 된다는 것을 알게 되었다.
$ sudo port install webkit2-gtk
$ sudo port install webkit-gtk3
하지만 오래전 맥포트를 설치하고 방치했던 나는 이미 넣은 물건이 너무 낡아서 그 안의 구축이 성공하지 못했을지도 모른다.결과는 다음 명령으로 모두 삭제한 후 다시 설치했습니다.
$ sudo port -fp uninstall installed
중간에 의존 관계가 존재하지만 install이 실패하면 실패한 것만 제거하고 install이 성공합니다.sudo port clean 失敗したもの
sudo port install 失敗したもの
테스트
오류가 제거된 후 먼저 go-webkit2 테스트를 몇 개 이동해 보았습니다.
근데 자꾸 동작이 이상해서...
VSCode에서 테스트를 실행할 때 실패했으며 처리가 반환되지 않을 때 움직이지 않습니다.
절차를 실행하면 성공할 것이다. 이미 불안할 뿐이다.
그리고 웹oop의 테스트는 디버깅 운행 중에도 순조롭게 실행되지 않습니다.
나는 웹oop을 포기하고 go-webkit2로 노력하기로 했다.
기존 테스트에 없는 파일을 읽고 테스트하는 모드입니다.
test_simple.html
<!doctype html>
<html>
<head>
<title>test</title>
</head>
<body>
<button id="button1">test</button>
<div id="target"></div>
<script>
document.getElementById('button1').addEventListener('click', function() {
document.getElementById('target').innerHTML = '<p>good</p>';
});
</script>
</body>
</html>
simple_test.gofunc TestWebView_RunSimpleJS(t *testing.T) {
webView := NewWebView()
defer webView.Destroy()
loadOk := false
webView.Connect("load-failed", func() {
t.Errorf("load failed")
})
webView.Connect("load-changed", func(_ *glib.Object, loadEvent LoadEvent) {
switch loadEvent {
case LoadFinished:
webView.RunJavaScript(`document.getElementById("button1").click()`, func(result *gojs.Value, err error) {
if err != nil {
t.Errorf("RunJavaScript error: %s", err)
}
webView.RunJavaScript(`document.getElementsByTagName("body")[0].outerHTML`, func(result *gojs.Value, err error) {
resultString := webView.JavaScriptGlobalContext().ToStringOrDie(result)
fmt.Println(resultString)
if strings.Count(resultString, "<p>good</p>") > 1 {
loadOk = true
}
gtk.MainQuit()
})
})
}
})
f, err := os.OpenFile("test_simple.html", os.O_RDONLY, 0755)
if err != nil {
t.Errorf("File open err: %s", err)
}
defer f.Close()
scanner := bufio.NewScanner(f)
htmlData := ""
for scanner.Scan() {
htmlData = htmlData + scanner.Text() + "\n"
}
glib.IdleAdd(func() bool {
webView.LoadHTML(htmlData, "")
return false
})
gtk.Main()
if !loadOk {
t.Error("!loadOk")
}
}
결과적으로 절차를 순조롭게 집행하지 않아도 성공했다.API server listening at: 127.0.0.1:16583
dbus[55590]: Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that org.freedesktop.dbus-session.plist is loaded!
dbus[55594]: Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that org.freedesktop.dbus-session.plist is loaded!
<body>
<button id="button1">test</button>
<div id="target"><p>good</p></div>
<script>
document.getElementById('button1').addEventListener('click', function() {
document.getElementById('target').innerHTML = '<p>good</p>';
});
</script>
</body>
PASS
HTML 이름 자세히 보기
그러면 간단한 HTML 동작이 있기 때문에 이 이름의 페이지에서 뽑은 HTML을 삽입해서 자바스크립트를 실행하려고 합니다.
결국 안돼.
Javascript가 실행될 때까지 기다려도 반환되지 않습니다.
아직 조사의 여지가 있지만 시간도 지났기 때문에 이번에는 여기까지입니다
해보다
원래 script 탭에서 지정한 외부 스크립트가 획득되었는지, 일반적으로 보면 인증이 필요한 페이지인데 괜찮은지 등 여러 가지 검증이 부족합니다. 하지만 Webloop이 잘 움직일 수 있는지 알고 싶습니다.
또한 인증 정보를 함께 전달하고 JavaScript를 이동해야 하는 페이지에서만 실행하면 되지만 나도 이 점을 조사하고 싶다.
또 Golang에서 실행 중인 Headless Browser가 몇 개 있는데, 저쪽에서 사용할 수 있는지 보고 싶습니다.
P. S.
go-webkit2 지난 9월경 댓글을 보니 문서
/api/emoji.add
에는 오르지 않았지만 사용자 영패와 멀티파트 폼을 올리면 emoji를 추가할 수 있다고 적혀 있었다.야, API가 추가됐는지 좀 더 이른 단계에서 조사해야...orz
만약 이 API를 사용한 프로그램으로 바꾸었다면, 어쨌든 하고 싶은 일은 곧 이루어질 것이다.
여러분도 시간이 지나면 먼저 원하는 API를 제공했는지 확인해 보세요.
Reference
이 문제에 관하여(저는 Go가 쓴 Statefull의 Virtual Web Browser 라이브러리의 Surf로 자바스크립트를 처리해보고 싶어요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/from_Unknown/items/6a4171a29f5935eb039c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)