goqueryでHTMLを読み込んでも中身が空の時があります。
agoutiなど使って表示を待ってからとる方法もありますが、メモリなどの関係でブラウザを起動させたくない時にscriptを読み込んで変数を取得することもできます。
APIが用意されておらずwebsocketのみで値更新されていない場合向け。
まずはテスト用のHTMLに以下のようなものを用意しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <script src="http://code.jquery.com/jquery-3.3.1.js"></script> <script src="/js/aaa.js"></script> <script> let v1 = [ {a:1, b:"read", c:3.14}, {a:2, b:"get", c:1.414}, ]; </script> </head> <body> <div>some div</div> <div>other div</div> <script> let v2 = "aa"; </script> </body> </html> |
WebでなくFileなのでちょっと読み込み方を変えますが、こんな感じで始めます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package main import ( "fmt" "os" "github.com/PuerkitoBio/goquery" ) func main() { //通常はこれだけ //goq, _ := goquery.NewDocument("http://...") f, _ := os.Open("./projects/test/goquery_script/goquery_script.html") defer f.Close() goq, _ := goquery.NewDocumentFromReader(f) //ここからgoqueryテスト } |
とりあえずscriptのsrc一覧を見てみます。
1 2 3 4 5 6 7 8 |
goq.Find("script").Each(func(_ int, sc *goquery.Selection) { _url, _isSrc := sc.Attr("src") if _isSrc { fmt.Println(_url) } }) // http://code.jquery.com/jquery-3.3.1.js // /js/aaa.js |
ここに目当てのものがある場合には、そちらのURLを読み込みます。
べた書きされているものはText()
で取得できます。
1 2 3 4 5 6 7 8 9 10 |
text := goq.Find("script").Text() fmt.Println(text) /* let v1 = [ {a:1, b:"read", c:3.14}, {a:2, b:"get", c:1.414}, ]; let v2 = "aa"; */ |
scriptべた書き部分はhead内とbody内の2つありますが全部取得できます。
ここから正規表現を使って値を取り出します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
text := goq.Find("script").Text() //v1の抜き出し exp := regexp.MustCompile(`(?s)v1 = \[(.*)\]`) v1 := exp.FindString(text) //配列内の要素抜き出し exp = regexp.MustCompile(`\{a:(.*), b:"(.*)", c(.*)\}`) matchs := exp.FindAllStringSubmatch(v1, -1) for i := 0; i < len(matchs); i++ { fmt.Println(matchs[i][1], matchs[i][2], matchs[i][3]) } // 1 read 3.14 // 2 get 1.414 |
複数行マッチになるので前回やったようにsフラグを立てています。
要素名やスペース数などで面倒な時は、
exp = regexp.MustCompile(
\{.*:(.*),.*:"(.*)",.*:(.*)\}
)
のように;,
で囲まれる部分をグルーピングする方法もあります。
手間的にはagoutiでヘッドレスブラウザ使って取得する方が早そう。
別アプリの用意が必要ない分できるだけgoqueryで解決しておきたいけど、できることに限度もあるから使い分けを考えないと。