サイト内で使用されている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を洗い出すために以下の事を行なっています。
思ったよりサクっとできました
- sitemapにあるaタグのhref、タイトルを取得。
-
http://example.com/
がついていないかチェック。ついていなかったらつける。 - 重複が存在している場合は削除。(めっちゃdirty)
- 最後は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をどこにしたらいいのかはわからず
Go自体こういったコードを書くには向いてると思います!