htmlから本文を取得してみる。
package main
import (
"bufio"
"io"
"log"
"net/http"
"os"
"strings"
)
func main() {
url := "https://saitodev.co/article/%E3%83%A4%E3%83%96%E3%82%AC%E3%83%A9%E3%82%B7%E3%81%AE%E5%9F%B7%E5%BF%B5"
resp, err := http.Get(url)
defer resp.Body.Close()
if err != nil {
log.Fatal(err)
}
readMode := false
var content string
reader := bufio.NewReader(resp.Body)
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
n := strings.Index(line, "post-content")
if n >= 0 {
if readMode == false {
readMode = true
continue
} else {
break
}
}
if readMode == true {
content = content + line
}
}
file, err := os.Create("test.html")
if err != nil {
log.Fatal(err)
}
defer file.Close()
file.Write([]byte(content))
}
植物のミカタの任意のページのurlを取得する。Getでurlのソースコードを取得する。この中から本文のみ切り出したいので、本文の始まりと終わりの目印を探す。植物のミカタの記事詳細ページのHTMLは、
/** ヘッダやページのタイトルのHTML **/ <div class="post-content image-caption-format-1 entry"> /** 本文が記述されている箇所 **/ </div><!-- .post-content --> /** サイドバーやフッタのHTMLが続く **/
このような構成になっており、
<div class="post-content">で始まりコメントのpost-contentの記述で終わるので、post-contentがあるところを本文の切りだしの目印にする。次にreadMode := falseで、post-contentを見つけたらtrue、見つけなかったらfalseにするスイッチを作成しておく。最初はfalseにしておく。本文の中身を入れる変数をvar content stringで作成する。
NewReaderでresp.BodyのBodyの部分だけをReader型の構造体で取り出す。 reader.ReadStringで構造体の中の一文ずつを切りだす(一文の区切りは\nで認識)。
n := strings.Index(line, "post-content")でlineの中にpost-contentが含まれるか検索する。post-contentが開始されるインデックスがint型で返るのでn > 0であれば、post-contentがlineに含まれていることになる。
if n >= 0 で、post-contentがあれば、readModeがfalseであれば、readMode = trueにして、continueによりforから始まる一番上の行に返り、lineを一行づつ読み込む。post-contentがないので、次は、if readMode == true に続き、content = content + lineでhtmlの本文を記録す、これをpost-contentが見つかるまで繰り返す。
本文の最後に記載されたpost-contentが見つかったら、if n >= 0 に戻るが、その際はreadModeがtrueのままになっているので、 if readMode == falseの条件を満たさないので、else に移り breakして、本文の読み込みを停止する。
os.Createでファイルを作成し、file.Writeでcontentの中身を書き込む。
これで本文だけのhtmlが取得できた。




