3.3 Response 结构体

Reponse结构体是我们请求Url后返回的响应。

这个结构体被定义在context结构中,我们在通过Addqueue或者Addqueue2将任务添加到任务队列后,框架会在合适的时机将任务取出进行解析。 我们可以通过ctx.GetResponse()来获取对应的Reponse结构(ctx为*Context结构),当然,ctx结构本身也提供了很多方法用于获取url抓取好的内容。

3.3.1 Response 定义

// Response represents an entity be crawled.用于装载抓取反馈的结构
type Response struct {
    // 原始请求
    *Request

    // 响应流,其中URL拷贝自*Request
    *http.Response

    // The text is body of response. http响应的body部分
    text string

    // The dom is a pointer of goquery boject that contains html result. goquery抓取下的dom树
    dom *goquery.Document

    // The items is the container of parsed result. Restful请求的KV数据
    items []map[string]interface{}

    // The files is the container of image. Restful请求的多媒体文件
    // "Name": string; "Body": io.ReadCloser
    files []map[string]interface{}

    // The err is not nil when crawl process is success. 错误码
    err error
}

3.3.2 Response 提供的一些public方法

// new一个新实例
func NewResponse(req *Request) *Response {
}

// 使用前的初始化工作
func (self *Response) Prepare(resp *http.Response, req *Request) *Response {
}

// GetError test whether download process success or not.
func (self *Response) GetError() error {
    return self.err
}

// SetError save err about download process.
func (self *Response) SetError(err error) {
    self.err = err
}

// AddItem saves KV string pair to Response.Items preparing for Pipeline
func (self *Response) AddItem(data map[string]interface{}) {
    self.items = append(self.items, data)
}

func (self *Response) GetItem(idx int) map[string]interface{} {
    return self.items[idx]
}

func (self *Response) GetItems() []map[string]interface{} {
    return self.items
}

// AddFile saves to Response.Files preparing for Pipeline
func (self *Response) AddFile(name ...string) {

}

func (self *Response) GetFile(idx int) map[string]interface{} {
    return self.files[idx]
}

func (self *Response) GetFiles() []map[string]interface{} {
    return self.files
}

// GetRequest returns request oject of self page.
func (self *Response) GetRequest() *Request {
    return self.Request
}

func (self *Response) GetHost() string {
    return self.Response.Request.URL.Host
}

func (self *Response) GetResponseHeader() http.Header {
    return self.Response.Header
}

func (self *Response) GetRequestHeader() http.Header {
    return self.Response.Request.Header
}

func (self *Response) GetReferer() string {
    return self.Response.Request.Header.Get("Referer")
}

// 自定义设置输出结果的"上级链接"字段
func (self *Response) SetReferer(referer string) *Response {
    self.Response.Request.Header.Set("Referer", referer)
    return self
}

// GetHtmlParser returns goquery object binded to target crawl result.
func (self *Response) GetDom() *goquery.Document {
    if self.dom == nil {
        self.initDom()
    }
    return self.dom
}

// GetHtmlParser returns goquery object binded to target crawl result. 
func (self *Response) initDom() *goquery.Document {
    r := strings.NewReader(self.GetText())
    var err error
    self.dom, err = goquery.NewDocumentFromReader(r)
    if err != nil {
        logs.Log.Error("%v", err)
        panic(err.Error())
    }
    return self.dom
}

// GetBodyStr returns plain string crawled.
func (self *Response) GetText() string {
    if self.text == "" {
        self.initText()
    }
    return self.text
}

func (self *Response) ResetText(body string) *Response {
    self.text = body
    self.dom = nil
    return self
}

如果response附带有kv数据,多媒体文件或者比较特殊的非文本响应,可以通过response获取。 如果反馈只是普通的html页面,使用ctx.GetText和ctx.GetDom就基本能够达到效果