其实爬虫的思路都是一样的,从网上获取下来一个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类型
最常用的也就这几种了
然后找到了之后就肯定有很多节点嘛,因为我自己是完全不会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年华东师范大学-法国高师集团联合培养研究生项"}]
自己看的话其实还是在终端里看起来清晰直观,至于什么还觉得不美观啥的,这就叫给前端解析了,俺不会了