質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.32%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

1回答

265閲覧

chromedpでのタイムアウトする方法がわからない

night

総合スコア8

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

0グッド

1クリップ

投稿2024/12/09 11:42

実現したいこと

golangのchromedpについて質問させてください。
chromedp.Runの中で、WaitVisibleなどで何か要素を待っている場合、
指定時間が経過しても待っている要素が表示されない場合に、
タイムアウトして、chromedp.Runの処理を抜け、その先の処理が進むようにしたいです。

発生している問題・分からないこと

何も考えず一生現れない要素を指定するとWaitVisibleで永遠待たれる事になります・・・
(厳密には何分かすればタイムアウトする??)

そこでタイムアウト機能をもたせようと、context.WithTimeoutを使ってみたのですが、
処理が正常に進んでもしなくても、指定時間でブラウザ全体が終了してしまいます。。
ブラウザは終了させず、残したままにしておきたいのです。

該当のソースコード

go

1package main 2 3import ( 4 "context" 5 "fmt" 6 "log" 7 "time" 8 9 "github.com/chromedp/chromedp" 10) 11 12func main() { 13 // ブラウザ起動オプションの設定 14 opts := append(chromedp.DefaultExecAllocatorOptions[:], 15 chromedp.Flag("headless", false), // ヘッドレスモードを解除 16 ) 17 18 allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...) 19 defer cancel() 20 21 ctx, cancel := chromedp.NewContext(allocCtx) 22 defer cancel() 23 24 // タイムアウトを設定 25 ctx, cancel := context.WithTimeout(ctx, 7*time.Second) 26 defer cancel() 27 28 // タスクの実行 29 var res string 30 err := chromedp.Run(ctx, 31 chromedp.Navigate("https://www.yahoo.co.jp/"), // Yahooのページを開く 32 chromedp.Title(&res), // ページタイトルを取得 33 chromedp.WaitVisible("#hoge"), // 出てこないであろう要素を待ってみる 34 ) 35 if err != nil { 36 // ここでタイムアウトを検知して何かの処理をする。 37 // ブラウザは終了させたくない。 38 fmt.Printf("エラーがでた: %s\n", err.Error()) 39 } 40 41 log.Printf("Page Title: %s", res) 42 43 fmt.Println("ブラウザは開いたままです。Enterキーを押して終了してください...") 44 fmt.Scanln() // ユーザーがEnterを押すまで待機 45}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

調べてはみたのですが、解決ができませんでした・・・
自分が欲しい情報にたどり着けなかったです。。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

https://github.com/chromedp/chromedp/issues/37#issuecomment-548271460

を試してみました。

go

1 2package main 3 4import ( 5 "context" 6 "fmt" 7 "log" 8 "time" 9 10 "github.com/chromedp/chromedp" 11) 12 13func RunWithTimeOut(ctx *context.Context, timeout time.Duration, tasks chromedp.Tasks) chromedp.ActionFunc { 14 return func(ctx context.Context) error { 15 timeoutContext, cancel := context.WithTimeout(ctx, timeout*time.Second) 16 defer cancel() 17 return tasks.Do(timeoutContext) 18 } 19} 20 21func main() { 22 // ブラウザ起動オプションの設定 23 opts := append(chromedp.DefaultExecAllocatorOptions[:], 24 chromedp.Flag("headless", false), // ヘッドレスモードを解除 25 ) 26 27 allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...) 28 defer cancel() 29 30 ctx, cancel := chromedp.NewContext(allocCtx) 31 defer cancel() 32 33 34 // タスクの実行 35 var res string 36 err := chromedp.Run(ctx, 37 chromedp.Navigate("https://www.yahoo.co.jp/"), // Yahooのページを開く 38 chromedp.Title(&res), // ページタイトルを取得 39 // chromedp.WaitVisible("#hoge"), // 出てこないであろう要素を待ってみる 40 RunWithTimeOut(&ctx, 3, chromedp.Tasks{ 41 chromedp.WaitVisible("#hoge"), 42 }), 43 ) 44 if err != nil { 45 // ここでタイムアウトを検知して何かの処理をする。 46 // ブラウザは終了させたくない。 47 fmt.Printf("エラーがでた: %s\n", err.Error()) 48 } 49 50 log.Printf("Page Title: %s", res) 51 52 fmt.Println("ブラウザは開いたままです。Enterキーを押して終了してください...") 53 fmt.Scanln() // ユーザーがEnterを押すまで待機 54} 55

でどうでしょう。

terminal

1エラーがでた: context deadline exceeded 22024/12/31 11:38:48 Page Title: Yahoo! JAPAN 3ブラウザは開いたままです。Enterキーを押して終了してください... 4

のような動きでした。Enterを押すブラウザーを閉じます。

投稿2024/12/31 02:43

TWSNMP

総合スコア121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

night

2025/01/31 14:19

ご回答ありがとうございます! 期待通りに動作しました 大変助かりました、ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.32%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問