このガイドで、あなたは学ぶことができる:
- 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
:使用するユーザーエージェント(例:web
、mobi
、またはカスタムユーザーエージェント)。 --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をまだインストールしていない場合は、公式ウェブサイトからダウンロードし、インストール手順に従ってください。
- Go IDE:Goエクステンション付きのVisual Studio Codeを推奨。
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番目のページネーション・ページに対応していることがわかる:
ウェブサイト全体をクロールするには、すべてのページネーションリンクをたどる必要があります。上の画像にあるように、ターゲットサイトには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がどのように構成されているかを理解するには、対象ページの商品要素を検査します:
この検査から、製品ページの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
スクリプトはこうあるべきだ:
- クリーンな状態からGospiderコマンドを実行する。
- 出力ファイルからすべてのURLを読み込む。
- 正規表現パターンを使って、商品ページのURLだけをフィルタリングする。
- フィルタリングされた製品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スクレイピング・スクリプトは次のようなものです:
- 先ほどGospiderとカスタムロジックを使って生成した
product_urls.txt
ファイルから商品ページのURLを読み込みます。 - 各商品ページにアクセスし、商品データをスクレイピングする。
- スクレイピングされた商品データを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に制限されています。本番用スクリプトでは、ニーズに応じてこの制限を解除または調整できます。
コリーは今、そうするだろう:
- リスト内の各URLにアクセスする。
OnHTML()
コールバックを適用して、商品データを抽出します。- 抽出したデータを
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
ファイルがプロジェクトフォルダに表示されます。それを開くと、スクレイピングされたデータが表形式できちんと構造化されているのがわかります:
はい、出来上がり!ゴスパイダーがクロール、コリーがスクレイピングの最強コンビだ。
ウェブ・クローリングに対するGospiderのアプローチの限界
Gospiderのクローリング・アプローチの最大の限界は以下の通りだ:
- リクエストが多すぎるためIP禁止。
- ウェブサイトがクローリングボットをブロックするために使用するクローリング対策技術。
その両方にどう取り組むか見てみよう!
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に登録し、プロキシサービスやスクレイピング製品を無料でお試しください!
クレジットカードは必要ありません