goquery_crawler

文章目录

      • 简述以及分析
      • 例子

借助goquery写个爬虫玩玩
hexo链接:https://woaixiaoyuyu.github.io/

简述以及分析

其实爬虫的思路都是一样的,从网上获取下来一个html静态网页,然后解析,过滤信息,找到自己想要的,或者找到绕过点,随之修改

在goquery中,每一个Document 代表一个将要被操作的 HTML 文档

有五种方法获取一个 Document 实例,分别是从一个 URL 创建、从一个 *html.Node 创建、从一个 io.Reader 创建、从一个 *http.Response 创建和从一个已有的 Document Clone 一个

我们从源码可以看出不管通过哪种函数实现哪种方法,返回值最后都是相同的,如下图

return newDocument(root, nil), nil

其实就是返回一个newDocument的函数

// Private constructor, make sure all fields are correctly filled.
func newDocument(root *html.Node, url *url.URL) *Document {
	// Create and fill the document
	d := &Document{nil, url, root}
	d.Selection = newSingleSelection(root, d)
	return d
}

而这个函数返回一个document的指针

我们接下来分析一下document和函数中那个selection的结构与关系

// Selection represents a collection of nodes matching some criteria. The
// initial Selection can be created by using Document.Find, and then
// manipulated using the jQuery-like chainable syntax and methods.
type Selection struct {
	Nodes    []*html.Node
	document *Document
	prevSel  *Selection
}

注释里写的挺明显的了,用document.Find过滤出特定的一些结点集合,这个集合就是selection

// Document represents an HTML document to be manipulated. Unlike jQuery, which
// is loaded as part of a DOM document, and thus acts upon its containing
// document, GoQuery doesn't know which HTML document to act upon. So it needs
// to be told, and that's what the Document class is for. It holds the root
// document node to manipulate, and can make selections on this document.
type Document struct {
	*Selection
	Url      *url.URL
	rootNode *html.Node
}

这个就不多做解释了,具体的Url,rootNode所含什么也可以在源码里面看到,需要了解了再看就好了

那么接下来按找步骤我们显然需要知道Document.Find这个函数怎么用,还是看源码

// Find gets the descendants of each element in the current set of matched
// elements, filtered by a selector. It returns a new Selection object
// containing these matched elements.
func (s *Selection) Find(selector string) *Selection {
	return pushStack(s, findWithMatcher(s.Nodes, compileMatcher(selector)))
}

可以看到本身document就包含一个selection,通过Find函数返回了一个新的selection,底下的具体函数没有在深入去看,感觉就是匹配的过程,毕竟有compile这个关键字

Find传入的这个参数是一个string类型

  1. doc.Find("#temp") //根据id查找
  2. doc.Find(".temp") //根据class查找
  3. doc.Find(“h1”).Find(“a”) //链式调用,根据标签查找

最常用的也就这几种了

然后找到了之后就肯定有很多节点嘛,因为我自己是完全不会jquery的,所以还是只能老老实实看源码了,要是会的大哥大姐们因该可以轻车熟路了

// Each iterates over a Selection object, executing a function for each
// matched element. It returns the current Selection object. The function
// f is called for each element in the selection with the index of the
// element in that selection starting at 0, and a *Selection that contains
// only that element.
func (s *Selection) Each(f func(int, *Selection)) *Selection {
	for i, n := range s.Nodes {
		f(i, newSingleSelection(n, s.document))
	}
	return s
}

字面意思,没一个指针代表一个selection,对每一个合适的元素执行函数f,返回的同样是一个selection,统计的下表默认从0开始,也就是是说第一个符合要求的的在原先selection中的selection的下表是0

会把传入的selection中的所有selection全都循环一遍,要是符合要求就执行函数f,这个函数f的内容由我们自己定义,现在看起来比较抽象,仔细想一下还是好理解的,实在不行下面给了个例子

然后

然后要是找到自己想要的内容结点的情况下,像输出内容直接.Text()就可以输出了,返回的是string类型,看一下源码

// Text gets the combined text contents of each element in the set of matched
// elements, including their descendants.
func (s *Selection) Text() string {
	var buf bytes.Buffer

	// Slightly optimized vs calling Each: no single selection object created
	var f func(*html.Node)
	f = func(n *html.Node) {
		if n.Type == html.TextNode {
			// Keep newlines and spaces, like jQuery
			buf.WriteString(n.Data)
		}
		if n.FirstChild != nil {
			for c := n.FirstChild; c != nil; c = c.NextSibling {
				f(c)
			}
		}
	}
	for _, n := range s.Nodes {
		f(n)
	}

	return buf.String()
}

由于 net/html 解析器要求文档必须是 UTF-8 编码,因此 goquery 库也有此要求。如果文档不是 UTF-8 编码,使用者需要自己转换

可以使用这个库:github.com/djimenez/iconv-go

例子

华师大研究生招生信息网信息,因为他正好没用utf-8编码

package main

import (
	"fmt"
	"net/http"

	"github.com/PuerkitoBio/goquery"
	iconv "github.com/djimenez/iconv-go" // 给这个库一个别名iconv
)

func test() {
	// connect
	res, err := http.Get("https://yjszs.ecnu.edu.cn/")
	if err != nil {
		fmt.Println("failed to connect")
	}
	defer res.Body.Close()
	// check status
	if res.StatusCode != http.StatusOK {
		fmt.Println("status code error")
	}
	// load HTML doc
	// 这里选择从一个 io.Reader 创建
	doc, err := goquery.NewDocumentFromReader(res.Body)
	if err != nil {
		fmt.Println("failed to load")
	}
	// 得到了 Document 实例后,通过 Dcoument.Find 方法获取一个 Selection 实例
	// 基于home3list这个class进行查找,然后遍历输出
	ansDoc := doc.Find(".home3list") // ansDoc 的类型是 *goquery.Selection
	ansDoc.Each(func(i int, contentSelection *goquery.Selection) {
		ans := contentSelection.Find("a").Text()
		// 转换格式
		ans, _ = iconv.ConvertString(ans, "GB2312", "utf-8")
		fmt.Println(i+1, ": ", ans)
	})
}

func main() {
	test()
}

输入结果如下

1 :  华东师范大学2020年硕士研究生招生考试初试自命题成
2 :  华东师范大学关于2020年硕士研究生招生考试初试成绩
3 :  华东师范大学2020年硕士研究生入学考试 艺术类考生
4 :  2020年“少数民族高层次骨干人才计划”研究生报考注
5 :  2020年“上海市教硕-规培相结合项目”招生简章
6 :  关于开展2020年硕士研究生招生网上咨询的通知
7 :  华东师范大学2020年硕士研究生招生专业目录
8 :  华东师范大学2020年硕士研究生招生简章
9 :  关于举办2020年研究生报考咨询活动的通知(校内场)
10 :  关于2019年硕士研究生录取通知书寄发的通知
11 :  华东师范大学2020年研究生招生宣传现场咨询会公告
12 :  关于2019级新生户口迁移党团组织转接及录取通知书相
13 :  2019年硕士研究生招生拟录取名单公示(不含推免生)
14 :  关于举办2019年暑期全国优秀大学生夏令营活动的通知
15 :  关于2019年硕士研究生拟录取后相关工作的通知
16 :  2020年上海市硕士研究生招生考试报名费电子发票已可
17 :  202001批次同等学力申硕课程考试准考证下载公告
18 :  202001批次同等学力申硕课程考试报名通知
19 :  2020年全国硕士研究生招生考试华东师范大学(311
20 :  华东师范大学研究生招生考试违规违法行为举报电话
21 :  华东师范大学考点2020年硕士研究生招生考试初试地点
22 :  华东师范大学考点(3111)2020年硕士研究生招生
23 :  201907批次同等学力申硕课程考试成绩公布公告
24 :  华东师范大学报考点(报考点代码3111)2020年硕
25 :  关于进一步严格规范硕士研究生招生考试培训行为的通知
26 :  关于推迟2020年面向香港、澳门、台湾地区研究生招生
                                                                        ...



27 :  2020年面向港澳台地区招收研究生华东师范大学报考点
                                                                        ...



28 :  华东师范大学2020年面向香港、澳门、台湾地区招收研
                                                                        ...



29 :  华东师范大学2019年面向香港、澳门、台湾地区招收研
                                                                        ...



30 :  关于2020年公费师范毕业生攻读非全日制教育硕士推迟
                                                                        ...


31 :  华东师范大学2020年推荐免试攻读硕士学位研究生拟录
                                                                        ...


32 :  华东师范大学2020年推免生(含直博生)接收专业和人
                                                                        ...


33 :  我校各院系2020年推免生(含直博生)接收方案

34 :  华东师范大学2020年推免生(含直博生)接收方案

35 :  2020年公费师范毕业生攻读非全日制教育硕士招生简章

36 :  2019年公费师范生申请攻读教育硕士专业学位拟录取名
                                                                        ...


37 :  关于申请2019年教育硕士的公费师范毕业生提交单位考
                                                                        ...


38 :  我校各院系2019年推免生(含直博生)接收方案

39 :  2019年免费师范毕业生攻读非全日制教育硕士招生简章

40 :  2019年推免生接收申请预报名的通知

41 :  关于我校2020年博士研究生招生近期工作的公告
42 :  华东师范大学2020年博士研究生招生“申请考核”专业
                                                                        ...

43 :  华东师范大学2020年博士研究生招生“申请考核”报考
                                                                        ...

44 :  华东师范大学2020年高校思想政治工作骨干在职攻读博
                                                                        ...

45 :  华东师范大学关于2020年在应届本科毕业生中招收博士
                                                                        ...

46 :  华东师范大学2020年高校思想政治理论课教师在职攻读
                                                                        ...

47 :  华东师范大学2020年招收攻读博士学位研究生报考办法
48 :  华东师范大学2020年“申请考核”方式招收博士研究生
                                                                        ...

49 :  华东师范大学2020年教育博士专业学位研究生招生简章
                                                                        ...

50 :  华东师范大学2020年教育博士专业学位研究生招生简章
                                                                        ...

51 :  华东师范大学2020年博士研究生招生简章
52 :  华东师范大学2020年招收攻读博士学位研究生指导教师
                                                                        ...

53 :  关于2019年博士研究生录取通知书寄发的通知
54 :  华东师范大学关于“定向新疆农业大学培养博士学历师资计
                                                                        ...

55 :  华东师范大学2019年博士研究生招生复试名单(普通招
                                                                        ...

56 :  2020年华东师范大学-法国高师集团联合培养研究生项
57 :  上海纽约大学2020年依托我校招收培养研究生
58 :  2019年华东师范大学-法国高师集团联合培养研究生项

可以看到有一些奇怪的省略号,我去官网上检查元素发现确实有,这其实不影响,我们在爬取的信息稍作修改就好

接下来试着把收到的信息完整的显示在新的网络页面上,用一下Gin框架吧

之前的代码也稍做修改,为了便于导入,创建了一个结构体切片

package main

import (
	"fmt"
	"net/http"

	"github.com/PuerkitoBio/goquery"
	iconv "github.com/djimenez/iconv-go" // 给这个库一个别名iconv
	"github.com/gin-gonic/gin"
)

type info struct {
	ID      int
	Content string
}

var information = make([]info, 0)

func test() {
	// connect
	res, err := http.Get("https://yjszs.ecnu.edu.cn/")
	if err != nil {
		fmt.Println("failed to connect")
	}
	defer res.Body.Close()
	// check status
	if res.StatusCode != http.StatusOK {
		fmt.Println("status code error")
	}
	// load HTML doc
	// 这里选择从一个 io.Reader 创建
	doc, err := goquery.NewDocumentFromReader(res.Body)
	if err != nil {
		fmt.Println("failed to load")
	}
	// 得到了 Document 实例后,通过 Dcoument.Find 方法获取一个 Selection 实例
	// 基于home3list这个class进行查找,然后遍历输出
	var temp info
	ansDoc := doc.Find(".home3list") // ansDoc 的类型是 *goquery.Selection
	ansDoc.Each(func(i int, contentSelection *goquery.Selection) {
		ans := contentSelection.Find("a").Text()
		// 转换格式
		ans, _ = iconv.ConvertString(ans, "GB2312", "utf-8")
		temp.ID = i + 1
		temp.Content = ans
		information = append(information, temp)
		//fmt.Println(i+1, ": ", ans)
		fmt.Println(information[i].ID, ":", information[i].Content)
	})
}

func main() {
	test()
	r := gin.Default()
	r.GET("/crawler", func(c *gin.Context) {
		data := information
		c.JSON(http.StatusOK, data)
	})
	r.Run(":9090")
}

我们可以在http://127.0.0.1:9090/crawler看见爬取的信息,但是乱得一塌糊涂,如下

[{"ID":1,"Content":"华东师范大学2020年硕士研究生招生考试初试自命题成"},{"ID":2,"Content":"华东师范大学关于2020年硕士研究生招生考试初试成绩"},{"ID":3,"Content":"华东师范大学2020年硕士研究生入学考试 艺术类考生"},{"ID":4,"Content":"2020年“少数民族高层次骨干人才计划”研究生报考注"},{"ID":5,"Content":"2020年“上海市教硕-规培相结合项目”招生简章"},{"ID":6,"Content":"关于开展2020年硕士研究生招生网上咨询的通知"},{"ID":7,"Content":"华东师范大学2020年硕士研究生招生专业目录"},{"ID":8,"Content":"华东师范大学2020年硕士研究生招生简章"},{"ID":9,"Content":"关于举办2020年研究生报考咨询活动的通知(校内场)"},{"ID":10,"Content":"关于2019年硕士研究生录取通知书寄发的通知"},{"ID":11,"Content":"华东师范大学2020年研究生招生宣传现场咨询会公告"},{"ID":12,"Content":"关于2019级新生户口迁移党团组织转接及录取通知书相"},{"ID":13,"Content":"2019年硕士研究生招生拟录取名单公示(不含推免生)"},{"ID":14,"Content":"关于举办2019年暑期全国优秀大学生夏令营活动的通知"},{"ID":15,"Content":"关于2019年硕士研究生拟录取后相关工作的通知"},{"ID":16,"Content":"2020年上海市硕士研究生招生考试报名费电子发票已可"},{"ID":17,"Content":"202001批次同等学力申硕课程考试准考证下载公告"},{"ID":18,"Content":"202001批次同等学力申硕课程考试报名通知"},{"ID":19,"Content":"2020年全国硕士研究生招生考试华东师范大学(311"},{"ID":20,"Content":"华东师范大学研究生招生考试违规违法行为举报电话"},{"ID":21,"Content":"华东师范大学考点2020年硕士研究生招生考试初试地点"},{"ID":22,"Content":"华东师范大学考点(3111)2020年硕士研究生招生"},{"ID":23,"Content":"201907批次同等学力申硕课程考试成绩公布公告"},{"ID":24,"Content":"华东师范大学报考点(报考点代码3111)2020年硕"},{"ID":25,"Content":"关于进一步严格规范硕士研究生招生考试培训行为的通知"},{"ID":26,"Content":"关于推迟2020年面向香港、澳门、台湾地区研究生招生\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t"},{"ID":27,"Content":"2020年面向港澳台地区招收研究生华东师范大学报考点\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t"},{"ID":28,"Content":"华东师范大学2020年面向香港、澳门、台湾地区招收研\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t"},{"ID":29,"Content":"华东师范大学2019年面向香港、澳门、台湾地区招收研\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t"},{"ID":30,"Content":"关于2020年公费师范毕业生攻读非全日制教育硕士推迟\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t"},{"ID":31,"Content":"华东师范大学2020年推荐免试攻读硕士学位研究生拟录\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t"},{"ID":32,"Content":"华东师范大学2020年推免生(含直博生)接收专业和人\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t"},{"ID":33,"Content":"我校各院系2020年推免生(含直博生)接收方案\n\t\t\t\t\t\t\t\t\t"},{"ID":34,"Content":"华东师范大学2020年推免生(含直博生)接收方案\n\t\t\t\t\t\t\t\t\t"},{"ID":35,"Content":"2020年公费师范毕业生攻读非全日制教育硕士招生简章\n\t\t\t\t\t\t\t\t\t"},{"ID":36,"Content":"2019年公费师范生申请攻读教育硕士专业学位拟录取名\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t"},{"ID":37,"Content":"关于申请2019年教育硕士的公费师范毕业生提交单位考\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t"},{"ID":38,"Content":"我校各院系2019年推免生(含直博生)接收方案\n\t\t\t\t\t\t\t\t\t"},{"ID":39,"Content":"2019年免费师范毕业生攻读非全日制教育硕士招生简章\n\t\t\t\t\t\t\t\t\t"},{"ID":40,"Content":"2019年推免生接收申请预报名的通知\n\t\t\t\t\t\t\t\t\t"},{"ID":41,"Content":"关于我校2020年博士研究生招生近期工作的公告"},{"ID":42,"Content":"华东师范大学2020年博士研究生招生“申请考核”专业\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t"},{"ID":43,"Content":"华东师范大学2020年博士研究生招生“申请考核”报考\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t"},{"ID":44,"Content":"华东师范大学2020年高校思想政治工作骨干在职攻读博\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t"},{"ID":45,"Content":"华东师范大学关于2020年在应届本科毕业生中招收博士\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t"},{"ID":46,"Content":"华东师范大学2020年高校思想政治理论课教师在职攻读\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t"},{"ID":47,"Content":"华东师范大学2020年招收攻读博士学位研究生报考办法"},{"ID":48,"Content":"华东师范大学2020年“申请考核”方式招收博士研究生\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t"},{"ID":49,"Content":"华东师范大学2020年教育博士专业学位研究生招生简章\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t"},{"ID":50,"Content":"华东师范大学2020年教育博士专业学位研究生招生简章\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t"},{"ID":51,"Content":"华东师范大学2020年博士研究生招生简章"},{"ID":52,"Content":"华东师范大学2020年招收攻读博士学位研究生指导教师\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t"},{"ID":53,"Content":"关于2019年博士研究生录取通知书寄发的通知"},{"ID":54,"Content":"华东师范大学关于“定向新疆农业大学培养博士学历师资计\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t"},{"ID":55,"Content":"华东师范大学2019年博士研究生招生复试名单(普通招\n\t\t\t\t\t\t\t\t\t...\n\t\t\t\t\t\t\t\t\t"},{"ID":56,"Content":"2020年华东师范大学-法国高师集团联合培养研究生项"},{"ID":57,"Content":"上海纽约大学2020年依托我校招收培养研究生"},{"ID":58,"Content":"2019年华东师范大学-法国高师集团联合培养研究生项"}]

后端处理的时候把多余的\t 给replace掉,最终代码如下

package main

import (
	"fmt"
	"net/http"
	"strings"

	"github.com/PuerkitoBio/goquery"
	iconv "github.com/djimenez/iconv-go" // 给这个库一个别名iconv
	"github.com/gin-gonic/gin"
)

type info struct {
	ID      int
	Content string
}

var information = make([]info, 0)

func test() {
	// connect
	res, err := http.Get("https://yjszs.ecnu.edu.cn/")
	if err != nil {
		fmt.Println("failed to connect")
	}
	defer res.Body.Close()
	// check status
	if res.StatusCode != http.StatusOK {
		fmt.Println("status code error")
	}
	// load HTML doc
	// 这里选择从一个 io.Reader 创建
	doc, err := goquery.NewDocumentFromReader(res.Body)
	if err != nil {
		fmt.Println("failed to load")
	}
	// 得到了 Document 实例后,通过 Dcoument.Find 方法获取一个 Selection 实例
	// 基于home3list这个class进行查找,然后遍历输出
	var temp info
	ansDoc := doc.Find(".home3list") // ansDoc 的类型是 *goquery.Selection
	ansDoc.Each(func(i int, contentSelection *goquery.Selection) {
		ans := contentSelection.Find("a").Text()
		// 转换格式
		ans, _ = iconv.ConvertString(ans, "GB2312", "utf-8")
		temp.ID = i + 1
		ans = strings.Replace(ans, "\t", "", -1)
		ans = strings.Replace(ans, "\n", "", -1)
		ans = strings.Replace(ans, "...", "", -1)
		temp.Content = ans
		information = append(information, temp)
		//fmt.Println(i+1, ": ", ans)
		fmt.Println(information[i].ID, ":", information[i].Content)
	})
}

func main() {
	test()
	r := gin.Default()
	r.GET("/crawler", func(c *gin.Context) {
		data := information
		c.JSON(http.StatusOK, data)
	})
	r.Run(":9090")
}

效果如下

[{"ID":1,"Content":"华东师范大学2020年硕士研究生招生考试初试自命题成"},{"ID":2,"Content":"华东师范大学关于2020年硕士研究生招生考试初试成绩"},{"ID":3,"Content":"华东师范大学2020年硕士研究生入学考试 艺术类考生"},{"ID":4,"Content":"2020年“少数民族高层次骨干人才计划”研究生报考注"},{"ID":5,"Content":"2020年“上海市教硕-规培相结合项目”招生简章"},{"ID":6,"Content":"关于开展2020年硕士研究生招生网上咨询的通知"},{"ID":7,"Content":"华东师范大学2020年硕士研究生招生专业目录"},{"ID":8,"Content":"华东师范大学2020年硕士研究生招生简章"},{"ID":9,"Content":"关于举办2020年研究生报考咨询活动的通知(校内场)"},{"ID":10,"Content":"关于2019年硕士研究生录取通知书寄发的通知"},{"ID":11,"Content":"华东师范大学2020年研究生招生宣传现场咨询会公告"},{"ID":12,"Content":"关于2019级新生户口迁移党团组织转接及录取通知书相"},{"ID":13,"Content":"2019年硕士研究生招生拟录取名单公示(不含推免生)"},{"ID":14,"Content":"关于举办2019年暑期全国优秀大学生夏令营活动的通知"},{"ID":15,"Content":"关于2019年硕士研究生拟录取后相关工作的通知"},{"ID":16,"Content":"2020年上海市硕士研究生招生考试报名费电子发票已可"},{"ID":17,"Content":"202001批次同等学力申硕课程考试准考证下载公告"},{"ID":18,"Content":"202001批次同等学力申硕课程考试报名通知"},{"ID":19,"Content":"2020年全国硕士研究生招生考试华东师范大学(311"},{"ID":20,"Content":"华东师范大学研究生招生考试违规违法行为举报电话"},{"ID":21,"Content":"华东师范大学考点2020年硕士研究生招生考试初试地点"},{"ID":22,"Content":"华东师范大学考点(3111)2020年硕士研究生招生"},{"ID":23,"Content":"201907批次同等学力申硕课程考试成绩公布公告"},{"ID":24,"Content":"华东师范大学报考点(报考点代码3111)2020年硕"},{"ID":25,"Content":"关于进一步严格规范硕士研究生招生考试培训行为的通知"},{"ID":26,"Content":"关于推迟2020年面向香港、澳门、台湾地区研究生招生"},{"ID":27,"Content":"2020年面向港澳台地区招收研究生华东师范大学报考点"},{"ID":28,"Content":"华东师范大学2020年面向香港、澳门、台湾地区招收研"},{"ID":29,"Content":"华东师范大学2019年面向香港、澳门、台湾地区招收研"},{"ID":30,"Content":"关于2020年公费师范毕业生攻读非全日制教育硕士推迟"},{"ID":31,"Content":"华东师范大学2020年推荐免试攻读硕士学位研究生拟录"},{"ID":32,"Content":"华东师范大学2020年推免生(含直博生)接收专业和人"},{"ID":33,"Content":"我校各院系2020年推免生(含直博生)接收方案"},{"ID":34,"Content":"华东师范大学2020年推免生(含直博生)接收方案"},{"ID":35,"Content":"2020年公费师范毕业生攻读非全日制教育硕士招生简章"},{"ID":36,"Content":"2019年公费师范生申请攻读教育硕士专业学位拟录取名"},{"ID":37,"Content":"关于申请2019年教育硕士的公费师范毕业生提交单位考"},{"ID":38,"Content":"我校各院系2019年推免生(含直博生)接收方案"},{"ID":39,"Content":"2019年免费师范毕业生攻读非全日制教育硕士招生简章"},{"ID":40,"Content":"2019年推免生接收申请预报名的通知"},{"ID":41,"Content":"关于我校2020年博士研究生招生近期工作的公告"},{"ID":42,"Content":"华东师范大学2020年博士研究生招生“申请考核”专业"},{"ID":43,"Content":"华东师范大学2020年博士研究生招生“申请考核”报考"},{"ID":44,"Content":"华东师范大学2020年高校思想政治工作骨干在职攻读博"},{"ID":45,"Content":"华东师范大学关于2020年在应届本科毕业生中招收博士"},{"ID":46,"Content":"华东师范大学2020年高校思想政治理论课教师在职攻读"},{"ID":47,"Content":"华东师范大学2020年招收攻读博士学位研究生报考办法"},{"ID":48,"Content":"华东师范大学2020年“申请考核”方式招收博士研究生"},{"ID":49,"Content":"华东师范大学2020年教育博士专业学位研究生招生简章"},{"ID":50,"Content":"华东师范大学2020年教育博士专业学位研究生招生简章"},{"ID":51,"Content":"华东师范大学2020年博士研究生招生简章"},{"ID":52,"Content":"华东师范大学2020年招收攻读博士学位研究生指导教师"},{"ID":53,"Content":"关于2019年博士研究生录取通知书寄发的通知"},{"ID":54,"Content":"华东师范大学关于“定向新疆农业大学培养博士学历师资计"},{"ID":55,"Content":"华东师范大学2019年博士研究生招生复试名单(普通招"},{"ID":56,"Content":"2020年华东师范大学-法国高师集团联合培养研究生项"},{"ID":57,"Content":"上海纽约大学2020年依托我校招收培养研究生"},{"ID":58,"Content":"2019年华东师范大学-法国高师集团联合培养研究生项"}]

自己看的话其实还是在终端里看起来清晰直观,至于什么还觉得不美观啥的,这就叫给前端解析了,俺不会了

你可能感兴趣的:(GO)