m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

golangでajaxを使用してrssのデータを取得する

データベース処理考え中

ORMマッパーとかあれば簡単だけどSQLを書きたい欲求もあり、コードを冗長化させない点を…

RSSのデータをjsonで取得

単純に記事のタイトルとリンクなどを取得するものを作成

構成

.
├── main.go
├── static
│   ├── css
│   │   ├── bootstrap-theme.css
│   │   ├── bootstrap-theme.css.map
│   │   ├── bootstrap-theme.min.css
│   │   ├── bootstrap-theme.min.css.map
│   │   ├── bootstrap.css
│   │   ├── bootstrap.css.map
│   │   ├── bootstrap.min.css
│   │   └── bootstrap.min.css.map
│   ├── fonts
│   │   ├── glyphicons-halflings-regular.eot
│   │   ├── glyphicons-halflings-regular.svg
│   │   ├── glyphicons-halflings-regular.ttf
│   │   ├── glyphicons-halflings-regular.woff
│   │   └── glyphicons-halflings-regular.woff2
│   └── js
│       ├── app.js
│       ├── bootstrap.js
│       ├── bootstrap.min.js
│       ├── jquery-2.2.0.min.js
│       ├── jquery-2.2.0.min.map
│       └── npm.js
└── templates
    └── index.html

実装

main.go
package main

// インポート
import (
	"log"
	"net/http"
	"html/template"
	"github.com/gorilla/mux"
	"io/ioutil"
	"encoding/xml"
	"encoding/json"
	"fmt"
)

// RSS一覧用
type RssListItem struct {
	Title       string
	Url         string
}

// RSS2用の構造体
type Rss2 struct {
	XMLName		xml.Name	`xml:"rss"`
	Version		string		`xml:"version,attr"`
	// Required
	Title		string		`xml:"channel>title"`
	Link		string		`xml:"channel>link"`
	Description	string		`xml:"channel>description"`
	// Optional
	PubDate		string		`xml:"channel>pubDate"`
	ItemList	[]Item		`xml:"channel>item"`
}

// RSS2の各記事の部分(Item)
type Item struct {
	// Required
	Title		string		`xml:"title"`
	Link		string		`xml:"link"`
	Description	template.HTML	`xml:"description"`
	// Optional
	Content		template.HTML	`xml:"encoded"`
	PubDate		string		`xml:"pubDate"`
	Comments	string		`xml:"comments"`
}

// RSSのjson用
type RssJsonList struct {
	Title    string `json:"title"`
	List     []RssJsonItem `json:"list"`
}
type RssJsonItem struct {
    Title     string `json:"title"`
    Link      string `json:"link"`
	Date      string `json:"date"`
}

// 主処理
func main(){

	// ルーティング初期化
	r := mux.NewRouter()

	// 静的ファイルをサポート
	r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))

	// url別処理
	r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){

		// テンプレート生成
        tmpl := template.Must(template.New("index").ParseFiles("templates/index.html"))
        // 変数を設定
        tmpl.Execute(w, struct{
			RssList []RssListItem
		}{
			RssList: []RssListItem{
				{
					Title: "m_shige1979のささやかな抵抗と欲望の日々",
					Url: "http://m-shige1979.hatenablog.com/rss",
				},
				{
                    Title: "ぎひょーさん",
                    Url: "http://gihyo.jp/feed/rss2",
                },
				{
                    Title: "@IT",
                    Url: "http://rss.rssad.jp/rss/itmatmarkit/rss.xml",
                },
			},
		})

		// log
		log.Print(r.URL.Path)

	})

	r.HandleFunc("/getRss", func(w http.ResponseWriter, r *http.Request){

		r.ParseForm()
		_url := r.FormValue("url")

		// httpよりRSS取得
		res, err := http.Get(_url)
		if err != nil {
			panic(err)
		}

		// text形式で読み込む
		asText, err2 := ioutil.ReadAll(res.Body)
		if err2 != nil {
			panic(err2)
		}

		// rss2構造体を定義
		rssData := Rss2{}

		// パースして格納
		err3 := xml.Unmarshal(asText, &rssData)
		if err3 != nil {
			panic(err3)
		}

		// json用に新規に用意
		var jsonData = RssJsonList{}
		jsonData.Title = rssData.Title
		jsonData.List = []RssJsonItem{}

		// 記事の部分を取得
		for _, value := range rssData.ItemList {
			jsonData.List = append(jsonData.List, RssJsonItem{Title: value.Title, Link: value.Link, Date: value.PubDate})
		}

        // jsonエンコード
        outputJson, err := json.Marshal(&jsonData)
        if err != nil {
            panic(err)
        }

        // jsonヘッダーを出力
        w.Header().Set("Content-Type", "application/json")

        // jsonデータを出力
        fmt.Fprint(w, string(outputJson))

		// log
		log.Print(r.URL.Path)
	})

	// ルーティング設定
	http.Handle("/", r)

	// ポート待ち
	log.Println(":9001")
	http.ListenAndServe(":9001", nil)
}
templates/index.html
{{ define "index" }}
<!DOCType html>
<html>
<head>
	<meta charset="utf-8" />
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>websample3</title>
	<link rel="stylesheet" href="/static/css/bootstrap.min.css" />
</head>
<body>
	<div class="container-fluid">
		<div class="row">
			<div class="col-xs-12">
				<h3>RSSリスト</h3>
				<ul>
					{{ range .RssList }}
					<li>
						<a href="javascript:void(0);" class="rss_click" data-url="{{ .Url }}">
							{{ .Title }}
						</a>
					</li>
					{{ end }}
				</ul>
			</div>
		</div>
		<hr />
		<div class="row">
			<div class="col-xs-12">
				<div class="rss_entry">
				</div>
				<div class="rss_item_tag" style="display: none;">
					<blockquote>
						<p class="date">aaaa</p>
						<p class="title">bbbb</p>
						<footer>
							<a href="cccc" target="_blank">xxxxx</a>
						</footer>
					</blockquote>
				</div>
			</div>
		</div>
	</div>
	<script src="/static/js/jquery-2.2.0.min.js"></script>
	<script src="/static/js/bootstrap.min.js"></script>
	<script src="/static/js/app.js"></script>
</body>
</html>
{{ end }}
static/js/app.js
$(function(){
	$(".rss_click").on("click", function(){
		var _url = $(this).attr("data-url");
		console.log(_url);

		// ajaxでrssを取得
		$.ajax({
			type: 'POST',
			url: '/getRss',
			data: {
				url: _url
			},
			dataType: 'json',
			success: function(data, status){
				console.log("success");
				console.log(data);

				// クリア
				$(".rss_entry").empty();
				for(var _key in data.list){
					var _itemElement = $(".rss_item_tag").clone(true);
					_itemElement.removeClass("rss_item_tag");
					_itemElement.css("display", "block");

					// rss情報設定
					_itemElement.find(".date").text(data.list[_key]["date"]);
					_itemElement.find(".title").text(data.list[_key]["title"]);
					_itemElement.find("footer > a").attr("href", data.list[_key]["link"]);
					_itemElement.find("footer > a").text(data.list[_key]["link"]);

					// 追加
					$(".rss_entry").append(_itemElement);
				}
			},
			error: function(err1, err2, err3){
				console.log("error");
			},
		});
	});
});

ソースのインデントが…まあいいか

結果

うん、まあこんなもんでいいかと

今回はこれで終わり