问题场景
准备在读取一个网络地址,获取页面的html标签结构和内容。找到一些方法,是通过读取
http.Get(testUrl)返回的HTTP response body resp *Response
的内容resp.Body再使用net/html库进行读取分析。第一次获取title 标签,第二次获取某个a
标签,但是第二次无法读到资源。
猜测
猜测指针在遍历时指向了结束,或许在一次读写后关闭了资源。需要再次进行打开读取? 通过复制的方式多搞几个再操作?
搜索 #Read Twice resp *Response # Body io.ReadCloser
得到的是继续向下追踪源代码进行思考。
实际上要追根溯源 resp.Body 的Body 是Body io.ReadCloser 而ReadCloser是一个接口
// ReadCloser is the interface that groups the basic Read and Close methods.
type ReadCloser interface {
Reader
Closer
}
这只得到了部分一个部分的解释,但是并没有给出为什么会造成只能读取一次的原理。
解决
通过"io/ioutil” 读取后创建多个副本来进行读取。
ioutil.ReadAll 返回 []byte 之后使用bytes.NewReader(b)
创建一个新的 *Reader
这种思想似乎印证的之前的猜测直接进行复制,但是为什么要使用ReadAll呢?
func main(){
resp, err := http.Get(testUrl)
if err != nil {
fmt.Println("errr--------")
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
//读取
if err !=nil{
panic(err)
}
//创建一个
reader := bytes.NewReader(b)
//创建第二个
readerTitle := bytes.NewReader(b)
videoSrc = alink.href(reader)
title = alink.Title(readerTitle)
...
}
- 参考: https://stackoverflow.com/questions/43021058/golang-read-request-body/43021236#43021236 https://siongui.github.io/2018/10/28/go-read-twice-from-same-io-reader/ https://books.google.com.hk/books?id=x7JADQAAQBAJ&pg=PA143&lpg=PA143&dq=go+html+parser+%E6%98%AF&source=bl&ots=HI-tth-153&sig=ACfU3U39vp_Xb9w-W3std3wiL39Ede8bug&hl=zh-CN&sa=X&redir_esc=y&sourceid=cndr#v=onepage&q=go%20html%20parser%20%E6%98%AF&f=false https://godoc.org/golang.org/x/net/html https://stackoverflow.com/questions/6564558/wildcards-in-the-pattern-for-http-handlefunc