2025年にGospiderでウェブクローリングを行う方法

GoでGospiderとCollyを使ったウェブクローリングをマスターしよう。セットアップ、スクレイピング、プロキシやアンチボットツールを使ってブロックを回避する方法を学びます。
10 分読
Web Crawling With Gospider blog image

このガイドで、あなたは学ぶことができる:

  • Gospiderとは?
  • 特徴
  • ウェブクローリングへの使用方法
  • ウェブスクレイピングのためにCollyと統合する方法
  • 主な制限とその回避方法

さあ、飛び込もう!

ゴスパイダーとは?

GospiderはGoで書かれた高速で効率的なウェブクローリングCLIツールです。ウェブサイトをスキャンしてURLを並列に抽出し、複数のリクエストとドメインを同時に処理するように作られています。さらに、robots.txtを尊重し、JavaScriptファイル内でもリンクを発見することができます。

Gospiderは、クロールの深さやリクエストの遅延などをコントロールするためのカスタマイズフラグをいくつか提供しています。また、クローリングプロセスをよりコントロールするための様々なオプションとともに、プロキシの統合もサポートしています。

ウェブクローリングにおけるGospiderの特徴は?

Gospiderがなぜウェブクローリングにとって特別なのかをよりよく理解するために、その機能を詳しく調べ、サポートされているフラグを調べてみましょう。

特徴

ウェブクローリングに関してGospiderが提供する主な機能は以下の通りです:

  • 高速ウェブクローリング:単一のウェブサイトを高速で効率的にクロールします。
  • 並列クロール:複数のサイトを同時にクロールし、データ収集を高速化。
  • sitemap.xmlの解析:クロールを強化するためにサイトマップファイルを自動的に処理します。
  • robots.txtの解析倫理的なクロールのためのrobots.txtディレクティブに準拠しています。
  • JavaScriptリンク解析:JavaScriptファイルからリンクを抽出します。
  • カスタマイズ可能なクロールオプション:クロールの深さ、同時実行、遅延、タイムアウトなどを柔軟なフラグで調整できます。
  • ユーザーエージェントのランダム化:より現実的なリクエストのために、モバイルとウェブのUser-Agentをランダム化します。ウェブクローリングに最適なUser-Agentを発見します。
  • クッキーとヘッダーのカスタマイズ:カスタムクッキーとHTTPヘッダーを許可します。
  • リンクファインダー:サイト上のURLやその他のリソースを特定する。
  • AWS S3 バケットを検索します:レスポンスソースからAWS S3バケットを検出します。
  • サブドメインの検索レスポンスソースからサブドメインを検出します。
  • サードパーティのソース:Wayback Machine、Common Crawl、VirusTotal、Alien VaultなどのサービスからURLを抽出します。
  • 簡単な出力フォーマットgrepや分析が容易なフォーマットで結果を出力。
  • Burp SuiteのサポートBurp Suiteとの統合により、テストとクロールがより簡単になりました。
  • 高度なフィルタリング:ドメインレベルのフィルタリングを含む、URLのブラックリストとホワイトリスト。
  • サブドメインのサポート:ターゲットサイトとサードパーティソースの両方からのクロールにサブドメインを含める。
  • デバッグと冗長モード:トラブルシューティングを容易にするために、デバッグと詳細なロギングを有効にします。

コマンドラインオプション

一般的なGospiderのコマンドはこんな感じ:

gospider [flags]

特に、サポートされているフラグは以下の通りである:

  • -s、-site:クロールするサイト。
  • -S、-sites:クロールするサイトのリスト。
  • p, --proxy: プロキシURL。
  • o, --output: 出力フォルダ。
  • u, --user-agent:使用するユーザーエージェント(例:webmobi、またはカスタムユーザーエージェント)。
  • --cookie: 使用するクッキー(例:testA=a; testB=b)。
  • H, --header:使用するヘッダ(複数のヘッダを使用する場合は、このフラグを複数回繰り返します)。
  • -burp文字列:Burp Suiteの生のHTTPリクエストからヘッダとクッキーを読み込む。
  • -ブラックリストブラックリストURL正規表現。
  • --whitelist:ホワイトリストURL正規表現。
  • --whitelist-domain:ホワイトリストのドメイン。
  • t, --threads:並列実行するスレッド数(デフォルト:1)。
  • c, --concurrent:一致するドメインの最大同時リクエスト数 (デフォルト:5)。
  • -d, --depth: URL の最大再帰深度 (0に設定すると無限再帰、デフォルトは1)。
  • k, --delay int: リクエスト間の遅延 (秒単位)。
  • K, --random-delay int: リクエストを実行するまでの遅延時間を秒単位でランダムに設定します。
  • m, --timeout int: リクエストタイムアウト(秒、デフォルト:10)。
  • B, --base: すべてを無効にし、HTMLコンテンツのみを使用する。
  • --js:JavaScriptファイルのリンクファインダーを有効にする(デフォルト:true)。
  • --subs: サブドメインを含める。
  • --sitemap:sitemap.xmlをクロールします。
  • --robots:robots.txtをクロールします(デフォルト:true)。
  • -a, --other-source: Archive.org、CommonCrawl、VirusTotal、AlienVaultのようなサードパーティのソースからURLを検索します。
  • w, --include-subs: 第三者ソースからクロールされたサブドメインを含める(デフォルト:メインドメインのみ)。
  • -r, --include-other-source: サードパーティのソースのURLも含めてクロールする。
  • --debug: デバッグモードを有効にする。
  • --json: JSON出力を有効にする。
  • v, --verbose: 冗長出力を有効にする。
  • l, --length: URLの長さを表示します。
  • -L, --filter-length: URLを長さでフィルタリングする。
  • R, --raw: 生の出力を表示する。
  • q, --quiet: すべての出力を抑制し、URLのみを表示する。
  • --no-redirect: リダイレクトを無効にする。
  • --version: バージョンをチェックする。
  • h, --help: ヘルプを表示する。

Gospiderでウェブクローリング:ステップバイステップガイド

このセクションでは、Gospiderを使ってマルチページサイトからリンクをクロールする方法を学びます。具体的には、対象サイトはBooks to Scrapeになります:

このサイトには、50ページにわたる商品リストが掲載されている。これらのリストページの各商品エントリは、それぞれ専用の商品ページも持っています。以下のステップでは、Gospiderを使ってすべての商品ページのURLを取得する方法を説明します!

前提条件とプロジェクトのセットアップ

作業を始める前に、以下のものが揃っていることを確認してください:

Goがインストールされていることを確認するには、以下を実行する:

go version

Goが正しくインストールされていれば、次のような出力が表示されるはずです(Windowsの場合):

go version go1.24.1 windows/amd64

素晴らしい!囲碁がセットアップされ、準備が整った。

新しいプロジェクトフォルダを作成し、ターミナルでそのフォルダに移動する:

mkdir gospider-project  
cd gospider-project  

これでGospiderをインストールし、ウェブクローリングに使用する準備が整いました!

ステップ1:Gospiderをインストールする

以下のgo installコマンドを実行して、Gospiderをコンパイルし、グローバルにインストールします:

go install github.com/jaeles-project/gospider@latest

インストール後、Gospiderがインストールされていることを確認してください:

gospider -h

すると、以下のようにGospiderの使用方法が表示されます:

Fast web spider written in Go - v1.1.6 by @thebl4ckturtle & @j3ssiejjj

Usage:
  gospider [flags]

Flags:
  -s, --site string               Site to crawl
  -S, --sites string              Site list to crawl
  -p, --proxy string              Proxy (Ex: http://127.0.0.1:8080)
  -o, --output string             Output folder
  -u, --user-agent string         User Agent to use
                                        web: random web user-agent
                                        mobi: random mobile user-agent
                                        or you can set your special user-agent (default "web")
      --cookie string             Cookie to use (testA=a; testB=b)
  -H, --header stringArray        Header to use (Use multiple flag to set multiple header)
      --burp string               Load headers and cookie from burp raw http request
      --blacklist string          Blacklist URL Regex
      --whitelist string          Whitelist URL Regex
      --whitelist-domain string   Whitelist Domain
  -L, --filter-length string      Turn on length filter
  -t, --threads int               Number of threads (Run sites in parallel) (default 1)
  -c, --concurrent int            The number of the maximum allowed concurrent requests of the matching domains (default 5)
  -d, --depth int                 MaxDepth limits the recursion depth of visited URLs. (Set it to 0 for infinite recursion) (default 1)
  -k, --delay int                 Delay is the duration to wait before creating a new request to the matching domains (second)
  -K, --random-delay int          RandomDelay is the extra randomized duration to wait added to Delay before creating a new request (second)
  -m, --timeout int               Request timeout (second) (default 10)
  -B, --base                      Disable all and only use HTML content
      --js                        Enable linkfinder in javascript file (default true)
      --sitemap                   Try to crawl sitemap.xml
      --robots                    Try to crawl robots.txt (default true)
  -a, --other-source              Find URLs from 3rd party (Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com)
  -w, --include-subs              Include subdomains crawled from 3rd party. Default is main domain
  -r, --include-other-source      Also include other-source's urls (still crawl and request)
      --subs                      Include subdomains
      --debug                     Turn on debug mode
      --json                      Enable JSON output
  -v, --verbose                   Turn on verbose
  -q, --quiet                     Suppress all the output and only show URL
      --no-redirect               Disable redirect
      --version                   Check version
  -l, --length                    Turn on length
  -R, --raw                       Enable raw output
  -h, --help                      help for gospider

驚いた!Gospiderがインストールされ、1つまたは複数のウェブサイトをクロールするために使用できるようになりました。

ステップ #2: ターゲットページのURLをクロールする

対象ページのすべてのリンクをクロールするには、以下のコマンドを実行する:

gospider -s "https://books.toscrape.com/" -o output -d 1

これは使用されたGospiderフラグの内訳である:

  • -s "https://books.toscrape.com/":ターゲットURLを指定する。
  • o 出力:クロール結果を出力フォルダに保存します。
  • -つまり、Gospiderは現在のページ上のURLのみを検出します。言い換えると、より深いリンクを発見するために発見されたURLをたどることはありません。

上記のコマンドは以下のような構造を生成する:

gospider-project/
  └── output/
        └── books_toscrape_com

出力フォルダ内のbooks_toscrape_comファイルを開くと、このような出力が表示されます:

[url] - [code-200] - https://books.toscrape.com/
[href] - https://books.toscrape.com/static/oscar/favicon.ico
# omitted for brevity...
[href] - https://books.toscrape.com/catalogue/page-2.html
[javascript] - http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
# omitted for brevity...
[javascript] - https://books.toscrape.com/static/oscar/js/bootstrap-datetimepicker/locales/bootstrap-datetimepicker.all.js
[url] - [code-200] - http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
# omitted for brevity...
[linkfinder] - [from: https://books.toscrape.com/static/oscar/js/bootstrap-datetimepicker/locales/bootstrap-datetimepicker.all.js] - dd/mm/yyyy
# omitted for brevity...
[url] - [code-200] - https://books.toscrape.com/static/oscar/js/bootstrap-datetimepicker/bootstrap-datetimepicker.js

生成されたファイルには、検出されたさまざまなタイプのリンクが含まれている:

  • [url]:クロールされたページ/リソース。
  • [href]:ページにあるすべての<a href>リンク。
  • [javascript]:JavaScriptファイルのURL。
  • [linkfinder]:JavaScriptコードに埋め込まれたリンクを抽出。

ステップ #3: サイト全体をクロールする

上の出力から、Gospiderが最初のページネーションページで停止したことがわかります。2ページ目へのリンクは検出されましたが、訪問しませんでした。

これは、books_toscrape_comファイルに含まれているので確認できる:

[href] - https://books.toscrape.com/catalogue/page-2.html

href]タグはリンクが発見されたことを示す。しかし、同じURLを持つ対応する[url]エントリが存在しないため、リンクは発見されたが訪問されなかったことになります。

ターゲット・ページを調べると、上記のURLが2番目のページネーション・ページに対応していることがわかる:

最初のページネーション・ページの "next "エレメントの検査

ウェブサイト全体をクロールするには、すべてのページネーションリンクをたどる必要があります。上の画像にあるように、ターゲットサイトには50の商品ページがあります(”Page 1 of 50 “のテキストに注目してください)。Gospiderの深度を50に設定し、すべてのページに到達するようにします。

これは大量のページをクロールすることになるので、同時実行率(つまり同時リクエスト数)を上げるのも良いアイデアです。デフォルトでは、Gospiderは同時実行レベル5を使用しますが、10に上げると実行速度が速くなります。

すべての商品ページをクロールする最後のコマンドは次のとおり:

gospider -s "https://books.toscrape.com/" -o output -d 50 -c 10

今回、Gospiderは実行に時間がかかり、何千ものURLを生成します。出力には次のようなエントリーが含まれます:

[url] - [code-200] - https://books.toscrape.com/
[href] - https://books.toscrape.com/static/oscar/favicon.ico
[href] - https://books.toscrape.com/static/oscar/css/styles.css
# omitted for brevity...
[href] - https://books.toscrape.com/catalogue/page-50.html
[url] - [code-200] - https://books.toscrape.com/catalogue/page-50.html

出力でチェックすべき重要な詳細は、最後のページネーションページのURLの有無である:

[url] - [code-200] - https://books.toscrape.com/catalogue/page-50.html

すばらしい!これでGospiderがすべてのページネーションリンクを正常にたどり、意図したとおりに製品カタログ全体をクロールしたことが確認できました。

ステップ4:商品ページのみを取得する

わずか数秒で、Gospiderはサイト全体のすべてのURLを収集しました。これでこのチュートリアルは終わりかもしれませんが、もう一歩進めてみましょう。

商品ページのURLだけを抽出したい場合はどうすればいいでしょうか?これらのURLがどのように構成されているかを理解するには、対象ページの商品要素を検査します:

製品HTML要素の検査

この検査から、製品ページのURLがこの形式に従っていることに気づくだろう:

https://books.toscrape.com/catalogue/<product_slug>/index.html

クロールされた生のURLから商品ページのみをフィルタリングするには、カスタムGoスクリプトを使用します。

まず、Gospiderプロジェクトのディレクトリ内にGoモジュールを作成します:

go mod init crawler

次に、プロジェクト・ディレクトリ内にクローラー・フォルダーを作成し、そこにcrawler.goファイルを追加する。次に、IDEでプロジェクト・フォルダーを開きます。フォルダ構造は次のようになるはずです:

gospider-project/
├── crawler/
│   └── crawler.go
└── output/
    └── books_toscrape_com

crawler.goスクリプトはこうあるべきだ:

  1. クリーンな状態からGospiderコマンドを実行する。
  2. 出力ファイルからすべてのURLを読み込む。
  3. 正規表現パターンを使って、商品ページのURLだけをフィルタリングする。
  4. フィルタリングされた製品URLを.txtファイルにエクスポートします。

以下はそのためのGoコードである:

package main

import (
        "bufio"
        "fmt"
        "os"
        "os/exec"
        "regexp"
        "slices"
        "path/filepath"
)

func main() {
        // Delete the output folder if it exists to start with a clean run
        outputDir := "output"
        os.RemoveAll(outputDir)

        // Create the Gospider CLI command to crawl the "books.toscrape.com" site
        fmt.Println("Running Gospider...")
        cmd := exec.Command("gospider", "-s", "https://books.toscrape.com/", "-o", outputDir, "-d", "50", "-c", "10")
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr

        // Run the Gospider command and wait for it to finish
        cmd.Run()
        fmt.Println("Gospider finished")

        // Open the generated output file that contains the crawled URLs
        fmt.Println("\nReading the Gospider output file...")
        inputFile := filepath.Join(outputDir, "books_toscrape_com")
        file, _ := os.Open(inputFile)
        defer file.Close()

        // Extract product page URLs from the file using a regular expression
        // to filter out the URLs that point to individual product pages
        urlRegex := regexp.MustCompile(`(https://books\.toscrape\.com/catalogue/[^/]+/index\.html)`)
        var productURLs []string

        // Read each line of the file and check for matching URLs
        scanner := bufio.NewScanner(file)
        for scanner.Scan() {
                line := scanner.Text()
                // Extract all URLs from the line
                matches := urlRegex.FindAllString(line, -1)
                for _, url := range matches {
                        // Ensure that the URL has not been added already to avoid duplicates
                        if !slices.Contains(productURLs, url) {
                                productURLs = append(productURLs, url)
                        }
                }
        }
        fmt.Printf("%d product page URLs found\n", len(productURLs))

        // Export the product page URLs to a new file
        fmt.Println("\nExporting filtered product page URLs...")
        outputFile := "product_urls.txt"
        out, _ := os.Create(outputFile)
        defer out.Close()

        writer := bufio.NewWriter(out)
        for _, url := range productURLs {
                _, _ = writer.WriteString(url + "\n")
        }
        writer.Flush()
        fmt.Printf("Product page URLs saved to %s\n", outputFile)
}

Goプログラムは、ウェブクローリングを自動化する:

  • os.RemoveAll()を使って出力ディレクトリ(output/)を削除する(すでに存在する場合)。
  • exec.Command()cmd.Run()を使用して、Gospiderのコマンドラインプロセスを構築、実行し、対象のウェブサイトをクロールします。
  • os.Open()bufio.NewScanner()でGospiderが生成した出力ファイル(books_toscrape_com)を開き、一行ずつ読み込む。
  • regexp.MustCompile()FindAllString()を使って、正規表現を使って各行から商品ページのURLを抽出し、slices.Contains()を使って重複を防ぎます。
  • os.Create()bufio.NewWriter()を使用して、フィルタリングされた商品ページのURLをproduct_urls.txtファイルに書き込みます。ステップ #5: クローリングスクリプトの実行 以下のコマンドでcrawler.goスクリプトを起動します:
go run crawler/crawler.go

スクリプトはターミナルに次のようにログを残す:

Running Gospider...
# Gospider output omitted for brevity...
Gospider finished

Reading the Gospider output file...
1000 product page URLs found

Exporting filtered product page URLs...
Product page URLs saved to product_urls.txt

Gospiderのクロールスクリプトは1,000の商品ページURLを見つけることに成功しました。ターゲットサイトで簡単に確認できるように、これはまさに利用可能な商品ページの数です:

対象サイトの商品カウンター

これらのURLは、プロジェクト・フォルダーに生成されたproduct_urls.txtファイルに保存されます。そのファイルを開くと

https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html
# omitted for brevity...
https://books.toscrape.com/catalogue/frankenstein_20/index.html

おめでとう!あなたはGoでウェブクローリングを実行するGospiderスクリプトを構築しました。

[おまけ】Gospiderクローラーにスクレイピング・ロジックを追加する

ウェブクローリングは一般的に、より大規模なウェブスクレイピングプロジェクトの1つのステップに過ぎません。この2つの手法の違いについては、ウェブクローリングとウェブスクレイピングに関するガイドをお読みください。

このチュートリアルをより完全なものにするために、クロールしたリンクをウェブスクレイピングに使用する方法も示します。これから作成するGoスクレイピング・スクリプトは次のようなものです:

  1. 先ほどGospiderとカスタムロジックを使って生成したproduct_urls.txtファイルから商品ページのURLを読み込みます。
  2. 各商品ページにアクセスし、商品データをスクレイピングする。
  3. スクレイピングされた商品データをCSVファイルにエクスポートします。

Gospiderのセットアップにウェブスクレイピングロジックを追加する時が来ました!

ステップ1: Collyのインストール

ウェブスクレイピングに使うライブラリはCollyで、Golang用のエレガントなスクレイパーとクローラーフレームワークだ。APIについてよく知らない場合は、Goを使ったウェブスクレイピングのチュートリアルをご覧ください。

以下のコマンドを実行してCollyをインストールする:

go get -u github.com/gocolly/colly/...

次に、プロジェクトディレクトリ内のscraperフォルダ内にscraper.goファイルを作成します。これで、プロジェクトの構造は次のようになるはずだ:

gospider-project/
├── crawler/
│   └── crawler.go
├── output/
│   └── books_toscrape_com
└── scraper/
    └── scraper.go

scraper.goを開き、Collyをインポートする:

import (
        "bufio"
        "encoding/csv"
        "os"
        "strings"

        "github.com/gocolly/colly"
)

素晴らしい!以下の手順に従って、Collyを使ってクロールされた商品ページからデータをスクレイピングしてください。

ステップ2:スクレイピングするURLを読む

以下のコードを使用して、crawler.goが生成したfiltered_urls.txtファイルから、スクレイピングする商品ページのURLを取得する:

// Open the input file with the crawled URLs
file, _ := os.Open("product_urls.txt")
defer file.Close()

// Read page URLs from the input file
var urls []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
        urls = append(urls, scanner.Text())
}

上記のスニペットを動作させるには、ファイルの先頭に以下のインポートを含める:

import (
        "bufio"
        "os"
)

素晴らしい!urlsスライスには、スクレイピング可能なすべての商品ページのURLが含まれます。

ステップ3:データ抽出ロジックの実装

データ抽出ロジックを実装する前に、商品ページのHTML構造を理解する必要があります。

これを行うには、ブラウザでシークレットモードで商品ページにアクセスし、新しいセッションを確保する。DevToolsを開き、商品画像のHTMLノードからページ要素を検査します:

商品画像要素の検査

次に、製品情報セクションを点検する:

製品情報要素

検査された要素から、あなたは抽出することができる:

  • <h1>タグの商品タイトル。
  • ページの最初の.price_colorノードからの商品価格。
  • .star-ratingクラスの製品評価(星)。
  • product_gallery img要素の商品画像URL。

これらの属性が与えられたら、スクレイピングされたデータを表すGo構造体を次のように定義します:

type Product struct {
        Title    string
        Price    string
        Stars    string
        ImageURL string
}

複数の商品ページがスクレイピングされるので、抽出された商品を保存するスライスを定義します:

var products []Product

データをスクレイピングするには、まずCollyCollectorを初期化します:

c := colly.NewCollector()

CollyのOnHTML()コールバックを使用してスクレイピングロジックを定義します:

c.OnHTML("html", func(e *colly.HTMLElement) {
        // Scraping logic
        title := e.ChildText("h1")
        price := e.DOM.Find(".price_color").First().Text()

        stars := ""
        e.ForEach(".star-rating", func(_ int, el *colly.HTMLElement) {
                class := el.Attr("class")
                if strings.Contains(class, "One") {
                        stars = "1"
                } else if strings.Contains(class, "Two") {
                        stars = "2"
                } else if strings.Contains(class, "Three") {
                        stars = "3"
                } else if strings.Contains(class, "Four") {
                        stars = "4"
                } else if strings.Contains(class, "Five") {
                        stars = "5"
                }
        })

        imageURL := e.ChildAttr("#product_gallery img", "src")
        // Adjust the relative image path
        imageURL = strings.Replace(imageURL, "../../", "https://books.toscrape.com/", 1)

        // Create a new product object with the scraped data
        product := Product{
                Title:    title,
                Price:    price,
                Stars:    stars,
                ImageURL: imageURL,
        }

        // Append the product to the products slice
        products = append(products, product)
})

.star-ratingのclass属性に基づいて星の評価を取得するために使用されるelse if構造に注意してください。また、strings.Replace()を使用して、相対画像URLを絶対URLに変換する方法も参照してください。

以下の必要なインポートを追加する:

import (
        "strings"
)

これで、Goスクレイパーは希望する商品データを抽出するように設定されました!

ステップ#4: ターゲットページに接続する

Collyはコールバック・ベースのウェブ・スクレイピング・フレームワークで、特定のコールバック・ライフサイクルを持つ。つまり、HTMLを取得する前にスクレイピングのロジックを定義することができ、これは珍しいが強力なアプローチだ。

データ抽出ロジックが整ったので、Collyに各商品ページを訪問するように指示する:

pageLimit := 50
for _, url := range urls[:pageLimit] {
        c.Visit(url)
}

注意: URLの数は、多数のリクエストでターゲットWebサイトを圧迫しないように、 50に制限されています。本番用スクリプトでは、ニーズに応じてこの制限を解除または調整できます。

コリーは今、そうするだろう:

  1. リスト内の各URLにアクセスする。
  2. OnHTML()コールバックを適用して、商品データを抽出します。
  3. 抽出したデータをproductsスライスに格納する。

驚きだ!あとはスクレイピングしたデータをCSVのような人間が読める形式にエクスポートするだけだ。

ステップ #5: スクレイピングしたデータをエクスポートする

以下のロジックを使用して、製品スライスをCSVファイルにエクスポートします:

outputFile := "products.csv"
csvFile, _ := os.Create(outputFile)
defer csvFile.Close()

// Initialize a new CSV writer
writer := csv.NewWriter(csvFile)
defer writer.Flush()

// Write CSV header
writer.Write([]string{"Title", "Price", "Stars", "Image URL"})

// Write each product's data to the CSV
for _, product := range products {
        writer.Write([]string{product.Title, product.Price, product.Stars, product.ImageURL})
}

上記のスニペットはproducts.csvファイルを作成し、スクレイピングされたデータをそのファイルに入力する。

Goの標準ライブラリからCSVパッケージをインポートすることを忘れないでください:

import (
       "encoding/csv"
)

いよいよです!これであなたのGospiderクローリングとスクレイピングプロジェクトは完全に実装されました。

ステップ6:すべてをまとめる

scraper.goの中身はこうなっているはずだ:

package main

import (
        "bufio"
        "encoding/csv"
        "os"
        "strings"

        "github.com/gocolly/colly"
)

// Define a data type for the data to scrape
type Product struct {
        Title    string
        Price    string
        Stars    string
        ImageURL string
}

func main() {
        // Open the input file with the crawled URLs
        file, _ := os.Open("product_urls.txt")
        defer file.Close()

        // Read page URLs from the input file
        var urls []string
        scanner := bufio.NewScanner(file)
        for scanner.Scan() {
                urls = append(urls, scanner.Text())
        }

        // Create an array where to store the scraped data
        var products []Product

        // Set up Colly collector
        c := colly.NewCollector()

        c.OnHTML("html", func(e *colly.HTMLElement) {
                // Scraping logic
                title := e.ChildText("h1")
                price := e.DOM.Find(".price_color").First().Text()

                stars := ""
                e.ForEach(".star-rating", func(_ int, el *colly.HTMLElement) {
                        class := el.Attr("class")
                        if strings.Contains(class, "One") {
                                stars = "1"
                        } else if strings.Contains(class, "Two") {
                                stars = "2"
                        } else if strings.Contains(class, "Three") {
                                stars = "3"
                        } else if strings.Contains(class, "Four") {
                                stars = "4"
                        } else if strings.Contains(class, "Five") {
                                stars = "5"
                        }
                })

                imageURL := e.ChildAttr("#product_gallery img", "src")
                // Adjust the relative image path
                imageURL = strings.Replace(imageURL, "../../", "https://books.toscrape.com/", 1)

                // Create a new product object with the scraped data
                product := Product{
                        Title:    title,
                        Price:    price,
                        Stars:    stars,
                        ImageURL: imageURL,
                }

                // Append the product to the products slice
                products = append(products, product)
        })

        // Iterate over the first 50 URLs to scrape them all
        pageLimit := 50 // To avoid overwhelming the target server with too many requests
        for _, url := range urls[:pageLimit] {
                c.Visit(url)
        }

        // Export the scraped products to CSV
        outputFile := "products.csv"
        csvFile, _ := os.Create(outputFile)
        defer csvFile.Close()

        // Initialize a new CSV writer
        writer := csv.NewWriter(csvFile)
        defer writer.Flush()

        // Write CSV header
        writer.Write([]string{"Title", "Price", "Stars", "Image URL"})

        // Write each product's data to the CSV
        for _, product := range products {
                writer.Write([]string{product.Title, product.Price, product.Stars, product.ImageURL})
        }
}

以下のコマンドでスクレーパーを起動する:

go run scraper/scraper.go

実行には時間がかかりますので、しばらくお待ちください。実行が完了すると、products.csvファイルがプロジェクトフォルダに表示されます。それを開くと、スクレイピングされたデータが表形式できちんと構造化されているのがわかります:

出力products.csvファイル

はい、出来上がり!ゴスパイダーがクロール、コリーがスクレイピングの最強コンビだ。

ウェブ・クローリングに対するGospiderのアプローチの限界

Gospiderのクローリング・アプローチの最大の限界は以下の通りだ:

  1. リクエストが多すぎるためIP禁止。
  2. ウェブサイトがクローリングボットをブロックするために使用するクローリング対策技術。

その両方にどう取り組むか見てみよう!

IPバンを避ける

同じマシンからのリクエストが多すぎる結果、あなたのIPアドレスがターゲットサーバーによって禁止される可能性があります。これはウェブクローリングでよくある問題で、特にうまく設定されていなかったり、倫理的に計画されていなかったりする場合に起こります。

デフォルトでは、Gospiderはrobots.txtを尊重し、このリスクを最小限に抑えます。しかし、すべてのウェブサイトにrobots.txtがあるとは限りません。また、robots.txtがあっても、クローラーに有効な速度制限ルールが指定されていない場合もあります。

IPバンを制限するには、Gospiderの組み込みの-delay--random-delay-timeoutフラグを使ってリクエストをスローダウンさせてみてください。しかし、適切な組み合わせを見つけるには時間がかかり、常に効果があるとは限りません。

より効果的な解決策は、Gospiderからの各リクエストが異なるIPアドレスから発信されることを保証するローテーションプロキシを使用することです。これにより、ターゲットサイトがあなたのクロールを検知し、ブロックすることを防ぎます。

Gospiderで回転プロキシを使うには、-p(または-proxy)フラグを付けてプロキシのURLを渡します:

gospider -s "https://example.com" -o output -p "<PROXY_URL>"

回転プロキシのURLをお持ちでない場合は、無料で取得してください!

クローリング防止技術を回避する

ローテーションプロキシであっても、ウェブサイトによっては厳密なスクレイピング対策やクローリング対策を実施しているものもあります。例えば、Cloudflareで保護されたウェブサイトに対してこのGospiderコマンドを実行する:

gospider -s "https://community.cloudflare.com/" -o output

結果はこうなる:

[url] - [code-403] - https://community.cloudflare.com/

ご覧の通り、ターゲットサーバーは403 Forbiddenレスポンスで応答しました。これは、サーバーがGospiderのリクエストを正常に検知してブロックし、ページ上のどのURLもクロールできないようにしたことを意味します。

このようなブロックを回避するには、オールインワンのウェブアンロックAPIが必要だ。このサービスは、アンチボットやアンチスクレイピング・システムを回避し、あらゆるウェブページのブロックされていないHTMLにアクセスすることができる。

:Bright DataのWeb Unlockerはこれらの課題を処理するだけでなく、プロキシとしても動作します。そのため、一度設定すれば、先に示した構文を使ってGospiderで通常のプロキシと同じように使うことができます。

結論

このブログポストでは、Gospiderとは何か、Gospiderが提供する機能とは何か、GoでのウェブクローリングにGospiderを使う方法について学びました。また、Collyと組み合わせて完全なクローリングとスクレイピングのチュートリアルを行う方法も紹介しました。

ウェブスクレイピングにおける最大の課題の1つは、IPバンやアンチスクレイピングソリューションによってブロックされるリスクです。これらの課題を克服する最善の方法は、ウェブプロキシやWeb UnlockerのようなスクレイピングAPIを使用することです。

Gospiderとの統合は、Bright Dataの製品やサービスがサポートする多くのシナリオの一つに過ぎません。他のウェブスクレイピングツールもご覧ください:

  • ウェブスクレーパーAPI:100以上の人気ドメインから新鮮で構造化されたウェブデータを抽出するための専用エンドポイント。
  • SERP API:SERPのすべての継続的なロック解除管理を処理し、1つのページを抽出するためのAPIです。
  • スクレイピング機能:スクレイパーをサーバーレス関数として実行できる完全なスクレイピング・インターフェース。
  • スクレイピング・ブラウザ:Puppeteer、Selenium、Playwright互換のブラウザで、ロック解除アクティビティが組み込まれています。

今すぐBright Dataに登録し、プロキシサービスやスクレイピング製品を無料でお試しください!

クレジットカードは必要ありません