使用Golang将许多数据从API解析为HTML。

huangapple go评论89阅读模式
英文:

Parse many data from api to html with golang

问题

我是Go语言的新手,所以我有一个问题。我有一个API,我需要从中解析信息到卡片中。我有一个脚本,它从API中获取所有信息,并将其放入卡片的字段中。我知道如何获取一部分信息。但是我需要根据API中的不同信息创建多个具有不同信息的卡片,并将它们放置在HTML页面上。我该如何做到这一点?

server.go文件用于HTML托管。

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"text/template"
)

type Response struct {
	Artists   string `json:"artists"`
	Locations string `json:"locations"`
	Dates     string `json:"dates"`
	Relation  string `json:"relation"`
}
type Artist struct {
	ID           int      `json:"id"`
	Image        string   `json:"image"`
	Name         string   `json:"name"`
	Members      []string `json:"members"`
	CreationDate string   `json:"creationDate"`
	FirstAlbum   string   `json:"firstAlbum"`
}

func main() {
	http.HandleFunc("/", formHandler) // 定义我们将使用的路径/页面,以及我们将使用的函数
	fmt.Printf("Starting server at port 8080\n")
	if err := http.ListenAndServe(":8080", nil); err != nil { // 在端口8080上初始化我们的服务器
		log.Fatal("HTTP status 500 - Internal server error: %s", err)
	}
}
func formHandler(w http.ResponseWriter, r *http.Request) {
	response, err := http.Get("https://groupietrackers.herokuapp.com/api")
	if err != nil {
		fmt.Print(err.Error())
		os.Exit(1)
	}

	responseData, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Fatal(err)
	}

	var responseObject Response

	json.Unmarshal(responseData, &responseObject)
	artist_link, err := http.Get(responseObject.Artists)
	if err != nil {
		fmt.Print(err.Error())
		os.Exit(1)
	}

	artistData, err := ioutil.ReadAll(artist_link.Body)
	if err != nil {
		log.Fatal(err)
	}

	var artistObject Artist

	json.Unmarshal(artistData, &artistObject)
	t, _ := template.ParseFiles("index.html")
	t.Execute(w, artistObject)
}

index.html文件用于向用户显示信息。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
</head>
<style>
    iframe {
        width: 99vw;
    }
    .card {
  box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
  transition: 0.3s;
  width: 40%;
}

.card:hover {
  box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}

.container {
  padding: 2px 16px;
}
    </style>
    
<body>

  <header>
    <h1>groupie-tracker</h1>
     </header>
    <div>
      {{range .}}
            <div class="card">
                <div class="container">
                  <h4><b>{{ .Name }}</b></h4> 
                  <p>{{ .FirstAlbum }}</p> 
                </div>
              </div>
              {{end}}
     </div>
</body>

</html>
英文:

I am new in Go language so I have a question. I have API from where I need to parse information to cards. I have a script which GET all information from API and place it into fields in card. I understand how to take one part of information. But I need to create many cards with different information from API and place them on HTML page. How I can do this?

server.go file for HTML hosting.

package main
import (
&quot;encoding/json&quot;
&quot;fmt&quot;
&quot;io/ioutil&quot;
&quot;log&quot;
&quot;net/http&quot;
&quot;os&quot;
&quot;text/template&quot;
)
type Response struct {
Artists   string `json:&quot;artists&quot;`
Locations string `json:&quot;locations&quot;`
Dates     string `json:&quot;dates&quot;`
Relation  string `json:&quot;relation&quot;`
}
type Artist struct {
ID           int      `json:&quot;id&quot;`
Image        string   `json:&quot;image&quot;`
Name         string   `json:&quot;name&quot;`
Members      []string `json:&quot;members&quot;`
CreationDate string   `json:&quot;creationDate&quot;`
FirstAlbum   string   `json:&quot;firstAlbum&quot;`
}
func main() {
http.HandleFunc(&quot;/&quot;, formHandler) // to define the path/page, where we are going to use the mentioned function
fmt.Printf(&quot;Starting server at port 8080\n&quot;)
if err := http.ListenAndServe(&quot;:8080&quot;, nil); err != nil { //to initialise our server on :8080
log.Fatal(&quot;HTTP status 500 - Internal server error: %s&quot;, err)
}
}
func formHandler(w http.ResponseWriter, r *http.Request) {
response, err := http.Get(&quot;https://groupietrackers.herokuapp.com/api&quot;)
if err != nil {
fmt.Print(err.Error())
os.Exit(1)
}
responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
var responseObject Response
json.Unmarshal(responseData, &amp;responseObject)
artist_link, err := http.Get(responseObject.Artists)
if err != nil {
fmt.Print(err.Error())
os.Exit(1)
}
artistData, err := ioutil.ReadAll(artist_link.Body)
if err != nil {
log.Fatal(err)
}
var artistObject Artist
json.Unmarshal(artistData, &amp;artistObject)
t, _ := template.ParseFiles(&quot;index.html&quot;)
t.Execute(w, artistObject)
}

index.html file for showing information to pearson.

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
&lt;title&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;style&gt;
iframe {
width: 99vw;
}
.card {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
width: 40%;
}
.card:hover {
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
.container {
padding: 2px 16px;
}
&lt;/style&gt;
&lt;body&gt;
&lt;header&gt;
&lt;h1&gt;groupie-tracker&lt;/h1&gt;
&lt;/header&gt;
&lt;div&gt;
{{range .}}
&lt;div class=&quot;card&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
&lt;h4&gt;&lt;b&gt;{{ .Name }}&lt;/b&gt;&lt;/h4&gt; 
&lt;p&gt;{{ .FirstAlbum }}&lt;/p&gt; 
&lt;/div&gt;
&lt;/div&gt;
{{end}}
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;

答案1

得分: 0

处理模板的方法有几种。但是你肯定希望解析文件一次并将它们存储起来。

一种方法是创建一个全局变量,并将模板/模板存储在其中。

此外,你期望一个 Artist 结构的切片,对吗?所以你想要解组成一个切片,而不是一个单独的对象。如果你检查解组时的错误,你会看到这一点。

最后,CreationDate 字段存在问题。解组错误也会显示出来。

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"text/template"
)

type Response struct {
	Artists   string `json:"artists"`
	Locations string `json:"locations"`
	Dates     string `json:"dates"`
	Relation  string `json:"relation"`
}
type Artist struct {
	ID           int      `json:"id"`
	Image        string   `json:"image"`
	Name         string   `json:"name"`
	Members      []string `json:"members"`
	CreationDate int      `json:"creationDate"`
	FirstAlbum   string   `json:"firstAlbum"`
}

var temp *template.Template

func main() {
	temp = template.Must(template.ParseFiles("index.html"))

	http.HandleFunc("/", formHandler) // to define the path/page, where we are going to use the mentioned function
	fmt.Printf("Starting server at port 8080\n")
	if err := http.ListenAndServe(":8080", nil); err != nil { //to initialise our server on :8080
		log.Fatal("HTTP status 500 - Internal server error: %s", err)
	}
}
func formHandler(w http.ResponseWriter, r *http.Request) {
	response, err := http.Get("https://groupietrackers.herokuapp.com/api")
	if err != nil {
		fmt.Print(err.Error())
		os.Exit(1)
	}

	responseData, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Fatal(err)
	}

	var responseObject Response

	json.Unmarshal(responseData, &responseObject)
	artist_link, err := http.Get(responseObject.Artists)
	if err != nil {
		fmt.Print(err.Error())
		os.Exit(1)
	}

	artistData, err := ioutil.ReadAll(artist_link.Body)
	if err != nil {
		log.Fatal(err)
	}

	var artists []Artist

	err = json.Unmarshal(artistData, &artists)
	if err != nil {
		log.Fatal(err)
	}

	temp.Execute(w, artists)
}
英文:

There are a couple ways to handle templates. But you definitely want to parse your files once and store them.

One way is to create a global var and store the template/templates in there.

Also you expect a slice of Artist structs, correct? So you want to unmarshal into a slice, not a single object. If you check the error on unmarshal, you will see that.

Last, there is a problem with the CreationDate field. Unmarshal error shows that too.

package main
import (
&quot;encoding/json&quot;
&quot;fmt&quot;
&quot;io/ioutil&quot;
&quot;log&quot;
&quot;net/http&quot;
&quot;os&quot;
&quot;text/template&quot;
)
type Response struct {
Artists   string `json:&quot;artists&quot;`
Locations string `json:&quot;locations&quot;`
Dates     string `json:&quot;dates&quot;`
Relation  string `json:&quot;relation&quot;`
}
type Artist struct {
ID           int      `json:&quot;id&quot;`
Image        string   `json:&quot;image&quot;`
Name         string   `json:&quot;name&quot;`
Members      []string `json:&quot;members&quot;`
CreationDate int      `json:&quot;creationDate&quot;`
FirstAlbum   string   `json:&quot;firstAlbum&quot;`
}
var temp *template.Template
func main() {
temp = template.Must(template.ParseFiles(&quot;index.html&quot;))
http.HandleFunc(&quot;/&quot;, formHandler) // to define the path/page, where we are going to use the mentioned function
fmt.Printf(&quot;Starting server at port 8080\n&quot;)
if err := http.ListenAndServe(&quot;:8080&quot;, nil); err != nil { //to initialise our server on :8080
log.Fatal(&quot;HTTP status 500 - Internal server error: %s&quot;, err)
}
}
func formHandler(w http.ResponseWriter, r *http.Request) {
response, err := http.Get(&quot;https://groupietrackers.herokuapp.com/api&quot;)
if err != nil {
fmt.Print(err.Error())
os.Exit(1)
}
responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
var responseObject Response
json.Unmarshal(responseData, &amp;responseObject)
artist_link, err := http.Get(responseObject.Artists)
if err != nil {
fmt.Print(err.Error())
os.Exit(1)
}
artistData, err := ioutil.ReadAll(artist_link.Body)
if err != nil {
log.Fatal(err)
}
var artists []Artist
err = json.Unmarshal(artistData, &amp;artists)
if err != nil {
log.Fatal(err)
}
temp.Execute(w, artists)
}

huangapple
  • 本文由 发表于 2021年12月19日 03:29:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/70406468.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定