文章目录
Go 爬虫抓取解析 xml
导入爬虫用到的库
1 2 3 4 5 6 7 8 9 10 11 |
import ( "encoding/xml" // xml 标准库 "fmt" // 打印" "io/ioutil" // ioutil 包实现了一些 I/O 实用函数。 "net/http" // http 请求库 ) |
定义抓取函数
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
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
主函数
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 循环遍历 } |
输出如下:

全部代码如下:
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
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) } } |

