Golangでウェブからデータをスクレイピングする方法 2025

goでウェブからデータをかき集める

Web scraping is a powerful technique for extracting data from websites, and Golang (Go) is an excellent language for this task. Known for its performance and efficiency, Go can handle web scraping with ease. So, how to scrape data from web with Golang? This guide will walk you through the process of scraping webpage using Golang, covering related techniques and tips.

Golangはウェブからのデータスクレイピングに適しているか?

Golangを使ったウェブからのデータスクレイピングについてもっと学ぶ前に、なぜウェブスクレイピングにGolangを選ぶのか、どんな利点があるのかを理解することが重要です。

Golangは、その高いパフォーマンス、効率的な並行処理モデル、そして堅牢な標準ライブラリにより、ウェブスクレイピングのための強力な選択肢です。ゴルーチンを使って複数のリクエストを同時に処理する能力と、HTTPリクエストとHTMLパース用の組み込みパッケージにより、Goは大量のデータを効率的にスクレイピングできます。また、CollyやGoqueryのようなサードパーティライブラリが追加機能を提供する。WebスクレイピングのためのPythonよりも一般的ではありませんが、Goの利点は、言語に精通している人々にとって魅力的な選択肢となります。

Golangでウェブデータをスクレイピングするための基本設定

Go(Golang)を使ってウェブからデータをスクレイピングするには、HTTPリクエストをしてウェブページを取得し、HTMLコンテンツを解析して必要な情報を抽出します。以下は、Goを使ってウェブからデータをスクレイピングするステップバイステップのガイドです:

    1. 環境を整える

      まず、Goがシステムにインストールされていることを確認してください。どちらも 公式サイト.

      ゴラン
    2. 必要なパッケージのインストール

      HTTPリクエストとHTMLパースにはいくつかのパッケージが必要だ。最もよく使われるパッケージは、HTTPリクエスト用のnet/httpとHTMLパース用のgoqueryである。

      のように実行して、特定のパッケージを取得する:

      go get github.com/PuerkitoBio/goquery

      スクレーパーの書き方

      ここでは、Golangを使ってウェブサイトからデータをスクレイピングする方法を簡単に説明します:

      パッケージメイン
      
      インポート (
          "fmt"
          "ログ"
          "net/http"
      
          "github.com/PuerkitoBio/goquery"
      )
      
      func main() {
          // スクレイピングするウェブサイトのURL
          url := "https://example.com"
      
          // HTTP GETリクエストを行う
          res, err := http.Get(url)
          if err != nil { もしerr !
              log.Fatal(err)
          }
          defer res.Body.Close()
      
          // レスポンスのステータスコードをチェックする
          if res.StatusCode != 200 { // レスポンス・ステータス・コードを確認します。
              log.Fatalf("Failed to fetch data: %d %s", res.StatusCode, res.Status)
          }
      
          // HTMLを解析する
          doc, err := goquery.NewDocumentFromReader(res.Body)
          if err != nil { もしerr !
              log.Fatal(err)
          }
      
          // データを検索して印刷する
          doc.Find("h1").Each(func(インデックス int, item *goquery.Selection) {)
              heading := item.Text()
              fmt.Println(heading)
          })
      }

      HTTPリクエストを行う:

      http.Get(url)は、指定されたURLにHTTP GETリクエストを行います。
      res.Body.Close()は、読み込み後にレスポンス・ボディが確実に閉じられるようにします。

      HTMLの解析:

      goquery.NewDocumentFromReader(res.Body)はHTMLレスポンスを解析し、goquery.Documentオブジェクトを返します。

      データの抽出:

      doc.Find("h1").Each()は、HTML内のすべてのh1要素を見つけ、それらを繰り返し処理する。
      item.Text() は、各h1要素のテキスト内容を抽出します。

    3. スクレーパーの運転

      上記のコードを、例えばmain.goのようなファイルに保存し、それを使って実行する:

      go run main.go

その他の考慮事項

エラーの処理スクレイパーが予期せずクラッシュしないように、常に適切にエラーを処理しましょう。

リスペクト robots.txt:ウェブサイトのrobots.txtファイルをチェックし、スクレイピングが許可されていることを確認する。

レート制限:サーバーをリクエストで圧倒しないように、レート制限を導入する。

ユーザーエージェント:スクレイパーを識別するためのカスタムUser-Agentヘッダを設定します:

req, err := http.NewRequest("GET", url, nil)
if err != nil { もしerr !
    log.Fatal(err)
}
req.Header.Set("User-Agent", "Golang_Scraper/1.0")

client := &http.Client{}とする。
res, err := client.Do(req)
if err != nil { もしerr !
    log.Fatal(err)
}
defer res.Body.Close()

// 前と同じようにHTMLを解析する

Golangでウェブデータをスクレイピングする高度なテクニック

ページネーションの処理

多くのウェブサイトはページネーションを使って複数のページにコンテンツを分割している。すべてのデータをスクレイピングするためには、各ページに順番にリクエストしてページネーションを処理する必要がある。

以下はページネーションの処理例である:

パッケージメイン

インポート (
    "fmt"
    "ログ"
    "net/http"
    "strconv"

    "github.com/PuerkitoBio/goquery"
)

func main() {
    baseURL := "https://example.com/page/"
    ページ := 1

    for {
        url := baseURL + strconv.Itoa(page)
        res, err := http.Get(url)
        if err != nil { もしerr !
            log.Fatal(err)
        }
        defer res.Body.Close()

        if res.StatusCode != 200 { } } log.Println("No more pages to fetch, stopping")
            log.Println("No more pages to fetch, stopping.")
            ブレーク
        }

        doc, err := goquery.NewDocumentFromReader(res.Body)
        if err != nil { もしerr !
            log.Fatal(err)
        }

        doc.Find(".item").Each(func(index int, item *goquery.Selection) {)
            title := item.Find(".title").Text()
            fmt.Println(title)
        })

        page++
    }
}

JavaScriptでレンダリングされたコンテンツを扱う

一部のウェブサイトでは、コンテンツを動的にレンダリングするためにJavaScriptを使用しています。GoにはJavaScriptを実行するビルトインの方法はありませんが ヘッドレスブラウザ Chromedpのように。

go get -u github.com/chromedp/chromedp

Chromedpを使用してJavaScriptでレンダリングされたコンテンツをスクレイピングする例:

パッケージメイン

インポート (
    "context"
    "fmt"
    "ログ"

    "github.com/chromedp/chromedp"
)

func main() {
    ctx, cancel := chromedp.NewContext(context.Background())
    cancel() を延期する。

    var htmlContent string

    err := chromedp.Run(ctx、
        chromedp.Navigate("https://example.com")、
        chromedp.OuterHTML("body", &htmlContent)、
    )
    if err != nil { もしerr !
        log.Fatal(err)
    }

    fmt.Println(htmlContent)
}

セッションとクッキーの管理

If a website requires login or session management, you can handle cookies and sessions using the http.CookieJar.

クッキーの管理例

パッケージメイン

インポート (
    "fmt"
    "ログ"
    "net/http"
    "net/http/cookiejar"

    "github.com/PuerkitoBio/goquery"
)

func main() {
    jar, _ := cookiejar.New(nil)
    client := &http.Client{Jar: jar}.

    // ログインしてクッキーを保存する
    loginURL := "https://example.com/login"
    ログインフォーム := url.Values{}
    loginForm.Set("username", "your_username")
    loginForm.Set("password", "your_password")

    res, err := client.PostForm(loginURL, loginForm)
    if err != nil { もしerr !
        log.Fatal(err)
    }
    res.Body.Close()

    // 保護されたページにアクセスする
    url := "https://example.com/protected-page"
    res, err = client.Get(url)
    if err != nil { もしerr !
        log.Fatal(err)
    }
    defer res.Body.Close()

    doc, err := goquery.NewDocumentFromReader(res.Body)
    if err != nil { もしerr !
        log.Fatal(err)
    }

    doc.Find(".protected-content").Each(func(インデックス int, item *goquery.Selection) {)
        content := item.Text()
        fmt.Println(content)
    })
}

スロットリングとレート制限

ウェブサイトにブロックされないようにするには、リクエスト間に遅延を導入してレート制限を行う。

レート制限の例:

パッケージメイン

インポート (
    "fmt"
    "ログ"
    "net/http"
    "時間"

    "github.com/PuerkitoBio/goquery"
)

func main() {
    urls := []string{"https://example.com/page1", "https://example.com/page2"}.

    for _, url := urls {の範囲
        res, err := http.Get(url)
        if err != nil { もしerr !
            log.Fatal(err)
        }
        defer res.Body.Close()

        doc, err := goquery.NewDocumentFromReader(res.Body)
        if err != nil { もしerr !
            log.Fatal(err)
        }

        doc.Find(".item").Each(func(index int, item *goquery.Selection) {)
            title := item.Find(".title").Text()
            fmt.Println(title)
        })

        // ブロックされないように遅延させる
        time.Sleep(2 * time.Second)
    }
}

AJAXリクエストの処理

ウェブサイトの中には、AJAXリクエストによって動的にデータをロードするものがある。ブラウザ開発者ツールのようなツールを使って、これらのリクエストをキャプチャし、APIエンドポイントを見つけるために複製することができる。

AJAX API エンドポイントからのデータ取得の例:

パッケージメイン

インポート(
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

type Item struct { (タイプアイテム構造体)
    タイトル文字列 `json: "title"`
}

func main() {
    url := "https://example.com/api/items"

    res, err := http.Get(url)
    if err != nil { もしerr !
        log.Fatal(err)
    }
    defer res.Body.Close()

    var items []アイテム
    if err := json.NewDecoder(res.Body).Decode(&items); err != nil { もしerr := json.NewDecoder(res.Body).Decode(&items); if err !
        log.Fatal(err)
    }

    for _, item := range items { {.
        fmt.Println(item.Title)
    }
}

キャプチャとスクレイピング防止機構を扱う

ウェブサイトはしばしばCAPTCHAやその他のスクレイピング防止メカニズムを使用しています。プログラムでCAPTCHAを解くのは複雑で、利用規約に反することも多いのですが、ユーザーエージェントやプロキシを回転させるなどのテクニックを使えば、検出を回避することができます。

回転するユーザーエージェントの例:

パッケージメイン

インポート (
    "fmt"
    "ログ"
    "net/http"
    "math/rand"
    "時間"
)

func main() {
    ユーザーエージェント := []string{
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"、
        「Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:54.0) Gecko/20100101 Firefox/54.0"、
        // ここに他のユーザーエージェントを追加する
    }

    client := &http.Client{}.
    rand.Seed(time.Now().UnixNano())

    for i := 0; i < 5; i++ { { { { for i := 0; i < 5; i++
        req, err := http.NewRequest("GET", "https://example.com", nil)
        if err != nil { もしerr !
            log.Fatal(err)
        }

        req.Header.Set("User-Agent", userAgents[rand.Intn(len(userAgents))])
        res, err := client.Do(req)
        if err != nil { もしerr !
            log.Fatal(err)
        }
        res.Body.Close()

        fmt.Println("Request sent with user-agent:", req.Header.Get("User-Agent"))
    }
}

プロキシの使用

あなたのIPがBANされないようにさらに保護するには、プロキシを使用することができます。OkeyProxyやMacroProxyのようなサービスがプロキシソリューションを提供しています。

As one of the best proxy providers, オッケープロキシー is supported by HTTP/HTTPS/SOCKS and provides 150 million+ real residential IPs, covering 200+ countries/areas, which could avoid IP ban ネットワーク接続のセキュリティ、信頼性、安定性を可能な限り確保します。

オッケープロキシー

Example of using a proxy for data scraping with http.Client:

パッケージメイン

インポート (
    "fmt"
    "ログ"
    "net/http"
    "net/url"
)

func main() {
    proxyURL, _ := url.Parse("http://proxyusername:proxypassword@proxyserver:port")
    トランスポート := &http.Transport{
        プロキシ:http.ProxyURL(proxyURL)、
    }

    client := &http.Client{Transport: transport}.

    res, err := client.Get("https://example.com")
    if err != nil { もしerr !
        log.Fatal(err)
    }
    defer res.Body.Close()

    fmt.Println("Response status:", res.Status)
}

コンカレント・スクレイピング

スクレイピングを高速化するために、ゴルーチンを使って複数のリクエストを同時に処理することができる。これは大きなデータセットをスクレイピングするのに便利です。

ゴルーチンによる並行スクレイピングの例:

パッケージメイン

インポート (
    "fmt"
    "ログ"
    "net/http"
    "同期"

    "github.com/PuerkitoBio/goquery"
)

func scrape(url文字列, wg *sync.WaitGroup) { { {{wg.Done()
    wg.Done()を延期する

    res, err := http.Get(url)
    if err != nil { もしerr !
        log.Println(err)
        return
    }
    defer res.Body.Close()

    doc, err := goquery.NewDocumentFromReader(res.Body)
    if err != nil { もしerr !
        log.Println(err)
        return
    }

    doc.Find(".item").Each(func(インデックス int, item *goquery.Selection) {)
        title := item.Find(".title").Text()
        fmt.Println(title)
    })
}

func main() {
    urls := []string{
        "https://example.com/page1"、
        "https://example.com/page2"、
        // URLを追加する
    }

    var wg sync.WaitGroup

    for _, url := 範囲 urls { // URLを追加する。
        wg.Add(1)
        go scrape(url, &wg)
    }

    wg.Wait()
}

APIからデータをスクレイピングする

多くのウェブサイトがデータにアクセスするためのAPIを提供している。APIを使うことは、HTMLをスクレイピングするよりも簡単で効率的なことが多い。

APIの呼び出し例:

パッケージメイン

インポート(
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

func main() {
    url := "https://api.example.com/data"

    res, err := http.Get(url)
    if err != nil { もしerr !
        log.Fatal(err)
    }
    defer res.Body.Close()

    var data map[string]interface{}
    if err := json.NewDecoder(res.Body).Decode(&data);err!
        log.Fatal(err)
    }

    fmt.Println("API Data:", data)
}

データの保存

要件によっては、スクレイピングしたデータをデータベースやファイルに保存する必要があるかもしれません。以下はCSVファイルにデータを書き込む例です:

パッケージメイン

インポート (
    "encoding/csv"
    "fmt"
    "ログ"
    "os"
    "net/http"
    "github.com/PuerkitoBio/goquery"
)

func main() {
    file, err := os.Create("data.csv")
    if err != nil { もしerr !
        log.Fatal(err)
    }
    defer file.Close()

    writer := csv.NewWriter(file)
    defer writer.Flush()

    urls := []string{"https://example.com/page1", "https://example.com/page2"}.

    for _, url := urls {の範囲
        res, err := http.Get(url)
        if err != nil { もしerr !
            log.Fatal(err)
        }
        defer res.Body.Close()

        doc, err := goquery.NewDocumentFromReader(res.Body)
        if err != nil { もしerr !
            log.Fatal(err)
        }

        doc.Find(".item").Each(func(index int, item *goquery.Selection) {)
            title := item.Find(".title").Text()
            writer.Write([]string{title})
        })
    }

    fmt.Println("data.csvに書き込まれたデータ")
}

エラー処理とログ

堅牢なエラー処理とロギングは、スクレイパーのトラブルシューティングと保守に不可欠です。Goのロギング機能またはlogrusのような外部ライブラリを使用して高度なロギングを行うことができます。

Golangでウェブスクレイピングをするための必須ライブラリ

  1. コリー強力で使いやすいウェブ・スクレイピング・フレームワーク。
  2. ゴクエリHTMLの操作とクエリのためのjQueryライクなライブラリ。インストール:go get -u github.com/PuerkitoBio/goquery
  3. リクエストインストール:go get -u github.com/imroc/req
  4. 遺贈PythonのRequestsに似た、高レベルのHTTPリクエスト・ライブラリ。
  5. クロームメッキChrome DevTools Protocolを使ったブラウザの自動化:インストール:go get -u github.com/chromedp/chromedp
  6. ロッド使いやすさとモダンな機能に重点を置いた、Go用のモダンなブラウザ自動化ライブラリ。
  7. ゴーセレンブラウザの自動化に便利な、Go用のSelenium WebDriverクライアントです。
  8. スコリーインストール: go get -u github.com/scolly/scolly
  9. ブロウショットインストール: go get -u github.com/browshot/browshot-go
  10. 人形遣い号Puppeteerは、ヘッドレスChromeをコントロールするためのNodeライブラリです。
  11. リクエストインストール:go get -u github.com/deckarep/golang-set
  12. Httpproxyインストール: go get -u github.com/henrylee2cn/httpproxy
  13. ハイハイインストール:go get -u github.com/whyrusleeping/crawling
  14. K6:K6 は主に負荷テストツールですが、スクリプト機能を使えばウェブデータのスクレイピングにも使えます。
  15. ネット/httpGoでHTTPリクエストを行うための標準ライブラリ:Goに組み込まれているため、別途インストールする必要はありません。
  16. ゴクエリ-htmlインストール:go get -u github.com/PuerkitoBio/goquery-html
  17. Httpclientインストール: go get -u github.com/aymerick/raymond

これらのライブラリやツールは、単純なHTTPリクエストから完全なブラウザ自動化まで、さまざまな機能をカバーしており、さまざまなウェブスクレイピングのニーズに対応できる。

概要

Golangを使ったウェブからのデータスクレイピングには、パフォーマンス効率や並行処理の容易さなど、いくつかの利点があります。Goの軽量なゴルーチンとチャンネルは、最小限のリソースオーバーヘッドで複数の同時リクエストを処理することができ、大規模なデータ抽出タスクに理想的です。さらに、Goの強力な標準ライブラリは、堅牢なHTTPおよびHTML解析機能をサポートしており、効率的で信頼性の高いWebスクレイピングアプリケーションの開発を簡素化します。このスピード、並行性、組み込みツールの組み合わせにより、Golangは高いパフォーマンスとスケーラビリティを必要とするウェブスクレイピングプロジェクトにとって魅力的な選択肢となっています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です