#はじめに
私が、Webマーケッターをやっていた頃、
エンジニアたちがよく、
「このページをスクレイピングして…DDoSならないように、秒間隔空けて…」
とかいうやりとりをしていて、
そう言えば、自分でもスクレイピングに憧れて、
import.io
とかいうスクレイピングの超便利サービスも使ってたなあと懐かしい思いがこみあげまして、、、
エンジニアになった自分もスクレイピングなるものを試してみようと思いたったので挑戦してみますた。
#ウェブスクレイピングとは
ウェブスクレイピング(英: Web scraping)とは、ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと。ウェブ・クローラー[1]あるいはウェブ・スパイダー[2]とも呼ばれる。 通常このようなソフトウェアプログラムは低レベルのHTTPを実装することで、もしくはウェブブラウザを埋め込むことによって、WWWのコンテンツを取得する。
参考:wikipedia ウェブスクレイピング
ほうほう、なるほど。(━うん、知ってた)
とりあえずページから情報を抽出できる感じ。
#goqueryを使ってみる
Goには、goquery というWebスクレイピング用の便利なライブラリが存在しているらしく、
他の記事でも試している人が多かったので、自分もこちらを採用。
jQuery
ライクに操作ができるので便利らしい。
##準備
必要なパッケージをダウンロードする。
$ go get -u github.com/PuerkitoBio/goquery # スクレイピングのライブラリ
$ go get -u github.com/saintfish/chardet # 文字コードの判定用
$ go get -u golang.org/x/net/html/charset # 文字コードの変換用
go.mod
でやる場合は、上記パッケージを記述後
go build
等をしてください〜
###※go get
のオプション
ざっくりと記します。詳しくは公式サイトへ
Go: Package get
go get
-d # only download (no install)
-u # update the packages & dependencies
-f # force -uと一緒に使い、-uがパッケージチェックするのを無効化する。利用シーンはソースがローカルコピーのとき
-t # test テストをビルドするパッケージもダウンロード
-v # verbose 進捗とデバッグ出力
-fix # 依存関係を修正
##コード
go gin のフレームワークを使って、REST API
を作成し、
URLを入力すると、そのページ先からタイトルを抽出して結果を返すmain.go
です。
(※エディタはgoland
を使いました。Go Modules
とかの管理が楽)
package main
import (
"bytes"
"fmt"
"golang.org/x/net/html/charset"
"io/ioutil"
"log"
"net/http"
"github.com/PuerkitoBio/goquery"
"github.com/gin-gonic/gin"
"github.com/saintfish/chardet"
)
func main() {
// Start HTTP server
r := gin.Default()
r.GET("/scrape", scrapeText)
if err := r.Run(":8080"); err != nil {
log.Fatal(err)
}
}
func scrapeText(c *gin.Context) {
url := c.Query("url")
// Getリクエストでレスポンス取得
res, _ := http.Get(url)
defer res.Body.Close()
// Body内を読み取り
buffer, _ := ioutil.ReadAll(res.Body)
// 文字コードを判定
detector := chardet.NewTextDetector()
detectResult, _ := detector.DetectBest(buffer)
fmt.Println(detectResult.Charset)
// => UTF-8
// 文字コードの変換
bufferReader := bytes.NewReader(buffer)
reader, _ := charset.NewReaderLabel(detectResult.Charset, bufferReader)
// HTMLをパース
document, _ := goquery.NewDocumentFromReader(reader)
// titleを抜き出し
result := document.Find("title").Text()
fmt.Println(result)
// Response: JSON
c.IndentedJSON(http.StatusOK, result)
}
htmlはテスト用です。(超ショボい・・・(´・ω・`))
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" charset="utf-8">
</head>
<body>
<form method="get" action="http://localhost:8080/scrape">
<p>URL<textarea name="url" size="30" placeholder="URL記入"></textarea></p>
<p><input type="submit" value="scrape"></p>
</form>
</body>
</html>
##実際に動かしてみる
とりあえず、フォームに鉄板の Yahoo! JAPAN を入れてみる。
やほおおおおお
###いざ!scrape
ボタンを押すと・・・
表示された!!
地味に嬉しい✨✨✨
#まとめ
今度は、複数のURLページにアクセスして、
GO Routine
とかChannels
なんかを使って、アプリケーションを拡張してみたいですねぇ。
前に形態素解析のライブラリのMeCabなんかも入れたから、
(GolangでMeCab+NEologdが使えるDockerイメージ作成してみた)
それと組み合わせて、
スクレイピングしてきたテキストを形態素解析にかけて遊ぶ
みたいなこともできそうです。
可能性、無限大!!!!!!!!!!!!
以上、ありがとうございました。
#参考にした記事たち
【Go】Webスクレイピングのやり方
goqueryでお手軽スクレイピング!
Goとgoqueryでスクレイピング
Go言語で jQuery ライクな操作が出来る goquery を試した。