Go 爬虫 解析 xml
Go 爬虫抓取解析 xml
导入爬虫用到的库
Python
import (
"encoding/xml"
// xml 标准库
"fmt"
// 打印"
"io/ioutil"
// ioutil 包实现了一些 I/O 实用函数。
"net/http"
// http 请求库
)
1
2
3
4
5
6
7
8
9
10
11
|
import (
"encoding/xml"
// xml 标准库
"fmt"
// 打印"
"io/ioutil"
// ioutil 包实现了一些 I/O 实用函数。
"net/http"
// http 请求库
)
|
定义抓取函数
Python
// 抓取 url xml 返回 []byte
func getXML(url string) ([]byte, error) {
resp, err := http.Get(url)
// 请求 url
if err != nil {
return []byte{}, fmt.Errorf("GET error: %v", err)
}
defer resp.Body.Close()
// 清理内存
if resp.StatusCode != http.StatusOK {
return []byte{}, fmt.Errorf("Status error: %v", resp.StatusCode)
}
// 根据状态码 判断是否正常
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []byte{}, fmt.Errorf("Read body: %v", err)
}
return data, nil
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// 抓取 url xml 返回 []byte
func getXML(url string) ([]byte, error) {
resp, err := http.Get(url)
// 请求 url
if err != nil {
return []byte{}, fmt.Errorf("GET error: %v", err)
}
defer resp.Body.Close()
// 清理内存
if resp.StatusCode != http.StatusOK {
return []byte{}, fmt.Errorf("Status error: %v", resp.StatusCode)
}
// 根据状态码 判断是否正常
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []byte{}, fmt.Errorf("Read body: %v", err)
}
return data, nil
}
|
xml 格式
定义xml 的 struct
Python
type rss struct {
XMLName xml.Name `xml:"rss"`
Items []itemD `xml:"channel>item"`
}
type itemD struct {
Title string `xml:"title"`
PubDate string `xml:"pubDate"`
Link string `xml:"link"`
}
1
2
3
4
5
6
7
8
9
10
11
|
type rss struct {
XMLName xml.Name `xml:"rss"`
Items []itemD `xml:"channel>item"`
}
type itemD struct {
Title string `xml:"title"`
PubDate string `xml:"pubDate"`
Link string `xml:"link"`
}
|
struct 和 xml 格式对应
rss struct 对应 xml
itemD struct 对应 xml
主函数
Python
func main() {
url :="https://rsshub.app/fx678/kx"
bytes,_:= getXML(url)
var ss rss
xml.Unmarshal(bytes,&ss)
// 解包
for index, value := range ss.Items{
fmt.Println(index,value.Link, value.PubDate, value.Title)
}
// 由于 ss.Items 是个数组,所以采用 for 循环遍历
}
1
2
3
4
5
6
7
8
9
10
11
12
13
|
func main() {
url :="https://rsshub.app/fx678/kx"
bytes,_:= getXML(url)
var ss rss
xml.Unmarshal(bytes,&ss)
// 解包
for index, value := range ss.Items{
fmt.Println(index,value.Link, value.PubDate, value.Title)
}
// 由于 ss.Items 是个数组,所以采用 for 循环遍历
}
|
输出如下:
全部代码如下:
Python
package main
import (
"encoding/xml"
"fmt"
"io/ioutil"
"net/http"
)
// 抓取 url xml 返回 []byte
func getXML(url string) ([]byte, error) {
resp, err := http.Get(url)
// 请求 url
if err != nil {
return []byte{}, fmt.Errorf("GET error: %v", err)
}
defer resp.Body.Close()
// 清理内存
if resp.StatusCode != http.StatusOK {
return []byte{}, fmt.Errorf("Status error: %v", resp.StatusCode)
}
// 根据状态码 判断是否正常
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []byte{}, fmt.Errorf("Read body: %v", err)
}
return data, nil
}
type rss struct {
XMLName xml.Name `xml:"rss"`
Items []itemD `xml:"channel>item"`
}
type itemD struct {
Title string `xml:"title"`
PubDate string `xml:"pubDate"`
Link string `xml:"link"`
}
// 变量一定要大写
// 定义结构体
func main() {
url :="https://rsshub.app/fx678/kx"
bytes,_:= getXML(url)
var ss rss
xml.Unmarshal(bytes,&ss)
for index, value := range ss.Items{
fmt.Println(index,value.Link, value.PubDate, value.Title)
}
// 由于 ss.Items 是个数组,所以采用 for 循环遍历
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
package main
import (
"encoding/xml"
"fmt"
"io/ioutil"
"net/http"
)
// 抓取 url xml 返回 []byte
func getXML(url string) ([]byte, error) {
resp, err := http.Get(url)
// 请求 url
if err != nil {
return []byte{}, fmt.Errorf("GET error: %v", err)
}
defer resp.Body.Close()
// 清理内存
if resp.StatusCode != http.StatusOK {
return []byte{}, fmt.Errorf("Status error: %v", resp.StatusCode)
}
// 根据状态码 判断是否正常
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []byte{}, fmt.Errorf("Read body: %v", err)
}
return data, nil
}
type rss struct {
XMLName xml.Name `xml:"rss"`
Items []itemD `xml:"channel>item"`
}
type itemD struct {
Title string `xml:"title"`
PubDate string `xml:"pubDate"`
Link string `xml:"link"`
}
// 变量一定要大写
// 定义结构体
func main() {
url :="https://rsshub.app/fx678/kx"
bytes,_:= getXML(url)
var ss rss
xml.Unmarshal(bytes,&ss)
for index, value := range ss.Items{
fmt.Println(index,value.Link, value.PubDate, value.Title)
}
// 由于 ss.Items 是个数组,所以采用 for 循环遍历
}
|
另外一个库 更方便 etree
Python
package main
import (
"fmt"
"github.com/levigross/grequests"
)
import "github.com/beevik/etree"
func main() {
url := "https://rsshub.app/fx678/kx"
xml_source, _ := grequests.Get(url, nil)
doc := etree.NewDocument()
if err := doc.ReadFromString(xml_source.String()); err != nil {
panic(err)
}
root := doc.SelectElement("rss")
root = root.SelectElement("channel")
for _, item := range root.SelectElements("item") {
title := item.SelectElement("title").Text()
url := item.SelectElement("link").Text()
fmt.Println(title, url)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package main
import (
"fmt"
"github.com/levigross/grequests"
)
import "github.com/beevik/etree"
func main() {
url := "https://rsshub.app/fx678/kx"
xml_source, _ := grequests.Get(url, nil)
doc := etree.NewDocument()
if err := doc.ReadFromString(xml_source.String()); err != nil {
panic(err)
}
root := doc.SelectElement("rss")
root = root.SelectElement("channel")
for _, item := range root.SelectElements("item") {
title := item.SelectElement("title").Text()
url := item.SelectElement("link").Text()
fmt.Println(title, url)
}
}
|
-
zeropython 微信公众号
5868037 QQ号
[email protected] QQ邮箱