Edited at

goqueryを使ってサイト内のCSSをスクレイピング

More than 1 year has passed since last update.

サイト内で使用されているCSSを確認しようとしたのですが、膨大なページがあったのでスクレイピングをする事にしました。その時に使用したgoqueryがとても便利でした。

他にもスクレイピング系ライブラリがあるみたいです。

Go言語のスクレイピング系ライブラリまとめ

goqueryの便利なところは、HTMLのselectorを指定できるので、jQuery感覚で記述できる点です。

以下は、githubからExamplesをお借りしました。


ExampleScrape.go

func ExampleScrape() {

doc, err := goquery.NewDocument("http://metalsucks.net")
if err != nil {
log.Fatal(err)
}

// Find the review items
doc.Find(".sidebar-reviews article .content-block").Each(func(i int, s *goquery.Selection) {
// For each item found, get the band and title
band := s.Find("a").Text()
title := s.Find("i").Text()
fmt.Printf("Review %d: %s - %s\n", i, band, title)
})
}


めちゃくちゃ読みやすくないですか?


sitemapから各ページで使用されているCSSを洗い出す

各ページで使用されているCSSを洗い出すために以下の事を行なっています。

思ったよりサクっとできました:thumbsup:


  1. sitemapにあるaタグのhref、タイトルを取得。


  2. http://example.com/がついていないかチェック。ついていなかったらつける。

  3. 重複が存在している場合は削除。(めっちゃdirty)

  4. 最後はURLを使って、各ページにアクセスし、CSSを取得・表示。


main.go

package main

import _ "fmt"

import (
"bytes"
"fmt"
"github.com/PuerkitoBio/goquery"
"regexp"
)

func main() {
urls := []string{}
titles := []string{}
doc, err := goquery.NewDocument("http://example.com/sitemap/")
if err != nil {
fmt.Print("url scarapping failed")
}
doc.Find("a").Each(func(_ int, s *goquery.Selection) {
url, _ := s.Attr("href")
title, _ := s.Html()
urls = append(urls, url)
titles = append(titles, title)
})
urls = removeDuplicate(createProtocolUrl(urls))
for i := range urls {
doc, err := goquery.NewDocument(urls[i])
if err != nil {
fmt.Print("\n", "child url scarapping failed", "\n")
}
doc.Find("[rel='stylesheet']").Each(func(_ int, s *goquery.Selection) {
cssPath, _ := s.Attr("href")
fmt.Print(titles[i], " -- ", urls[i], " -> ", cssPath, "\n")
})
}
}

func createProtocolUrl(urls []string) (result []string) {
arrayUrlHasProtocol := []string{}
for i := range urls {
var url string
if hasDomain(urls[i]) {
url = urls[i]
} else {
var buffer bytes.Buffer
buffer.WriteString("https://example.com")
buffer.WriteString(urls[i])
url = buffer.String()
}
if url != "" {
arrayUrlHasProtocol = append(arrayUrlHasProtocol, url)
}
}
return arrayUrlHasProtocol
}

func hasDomain(path string) bool {
return regexp.MustCompile(`^http://example.com/`).Match([]byte(path))
}

func removeDuplicate(args []string) []string {
results := make([]string, 0, len(args))
for i := 0; i < len(args); i++ {
dup := false
for j := 0; j < len(results); j++ {
if args[i] == results[j] {
dup = true
break
}
}
if !dup {
results = append(results, args[i])
}
}
return results
}



まとめ

スクレイピング自体どの言語を使っても割と簡単にできるので、今回はGo言語で行いました。

コードを書くよりも環境設定の方が時間かかりました。結局gopathをどこにしたらいいのかはわからず:cry:

Go自体こういったコードを書くには向いてると思います!