日記

更新頻度はあまり高くはありませんがネタがあったら書いていこうと思います。

GolangでSteamのセール情報を取得するクローラを作った。

Amazon.co.jp: Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例: るびきち, 佐々木 拓郎: 本 という本を読んでいて何か実際に実装してみたいなと思い、Steamのセールを取得して保存するクローラをGoで作成しました。
このソフトウェアではSteamのセールページをクローリングしてゲームのセール情報をすべて取り出すことができます。

Go言語で並列化を実装したので約400ページ、約6000ゲームの情報を10秒程で取得できます。また、取得したものをCSV形式でファイルに保存するようにしました。
並列化部分の実装は下記のようになっています。

// StartCrawl start crawling.
func (c *Crawler) StartCrawl() (err error) {
    doc, err := goquery.NewDocument(url)
    if err != nil {
        return
    }

    // Getting the number of pages.
    var pageNum int
    doc.Find(".search_pagination_right").Children().Each(func(i int, s *goquery.Selection) {
        if i == 2 {
            pageNum, err = strconv.Atoi(s.Text())
            if err != nil {
                return
            }
        }
    })

    // Starting goroutine.
    resultCh := make(chan []Game, pageNum)
    for i := 1; i < pageNum+1; i++ {
        url := fmt.Sprintf("%s&page=%d", url, i)
        go c.crawl(url, resultCh)
    }

    // Collectiong games.
    for i := 1; i < pageNum+1; i++ {
        gs := <-resultCh
        c.games = append(c.games, gs...)
    }
    close(resultCh)

    return
}

ページネーションからページ数を取得できるので、取得したページのURLを作成し、1ページにつき1つのGoroutineを稼働させChannelを使って回収しています。HTMLのスクレイピングにはgoqueryというライブラリを使用しました。

また、コードはすべてGithub上で公開しています。

github.com