2017-09-20 7 views
-1

Go를 사용하여 웹 스크레이퍼를 만들려고합니다. 언어에 익숙하지 않고 html 파서를 사용할 때 내가 뭘 잘못하고 있는지 잘 모르겠습니다. 앵커 태그를 찾기 위해 HTML을 구문 분석하려고하지만 html.TokenTypeEnd 대신 계속 가져옵니다. 내가 fmt.Printf("%T", tt)Go를 사용하여 HTML 구문 분석

+0

당신은 한 번만'response.Body'을 읽을 수 있습니다

코드

는 단순화 할 수있다. 'GetHtml' 함수에서 이미 사용되었습니다. 왜 HTML 문자열 전체를 읽고 어쨌든 던져 버리는거야? – RayfenWindspear

+0

저는 파이썬에 익숙해있어서 html을 읽고 문자열로 반환해야한다고 생각했습니다. 이것은 내가 작성한 첫 번째 Go 프로그램이며 나는이 언어를 아주 잘 알고 있으므로 이해하려고 노력 중입니다. – King

+0

'io.Reader' 나'io.ReadCloser's를 보았을 때 가능하다면 변수를 읽는 것을 피하고 싶습니다. 제대로 사용하면 작업을보다 효율적으로 수행 할 수있는 이러한 유형의 최적화가 있습니다. 이것이 바로 html.NewTokenizer가 첫 번째 이유입니다. 그냥 몇 가지 조언. 응답이 엄청나지 않다는 것이 확실하다면'ioutil.ReadAll'을 사용하는 것이 좋습니다. – RayfenWindspear

답변

2

응용 프로그램은 GetHtml에서 신체의 끝 부분에 읽기를 인쇄하고 있습니다 때마다

package main 

import (
    "fmt" 
    "golang.org/x/net/html" 
    "io/ioutil" 
    "net/http" 
) 

func GetHtml(url string) (text string, resp *http.Response, err error) { 
    var bytes []byte 
    if url == "https://www.coastal.edu/scs/employee" { 
     resp, err = http.Get(url) 
     if err != nil { 
      fmt.Println("There seems to ben an error with the Employee Console.") 
     } 
     bytes, err = ioutil.ReadAll(resp.Body) 
     if err != nil { 
      fmt.Println("Cannot read byte response from Employee Console.") 
     } 
     text = string(bytes) 
    } else { 
     fmt.Println("Issue with finding URL. Looking for: " + url) 
    } 

    return text, resp, err 
} 

func main() { 
    htmlSrc, response, err := GetHtml("https://www.coastal.edu/scs/employee") 
    if err != nil { 
     fmt.Println("Cannot read HTML source code.") 
    } 
    _ = htmlSrc 
    htmlTokens := html.NewTokenizer(response.Body) 
    i := 0 
    for i < 1 { 

     tt := htmlTokens.Next() 
     fmt.Printf("%T", tt) 
     switch tt { 

     case html.ErrorToken: 
      fmt.Println("End") 
      i++ 

     case html.TextToken: 
      fmt.Println(tt) 

     case html.StartTagToken: 
      t := htmlTokens.Token() 

      isAnchor := t.Data == "a" 
      if isAnchor { 
       fmt.Println("We found an anchor!") 
      } 

     } 

    } 

나는 html.TokenTypeEnd을 얻고있다. 본문의 읽기가 EOF를 반환하기 때문에 토크 나이저는 html.TokenTypeEnd을 반환합니다.

사용이 코드 :

htmlTokens := html.NewTokenizer(strings.NewReader(htmlSrc)) 

이 토크 나이를 만듭니다.

또한 연결 누출을 방지하려면 GetHtml의 응답 본문을 닫으십시오.

response, err := http.Get("https://www.coastal.edu/scs/employee") 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer resp.Body.Close() 
    htmlTokens := html.NewTokenizer(response.Body) 
loop: 
    for { 
     tt := htmlTokens.Next() 
     fmt.Printf("%T", tt) 
     switch tt { 
     case html.ErrorToken: 
      fmt.Println("End") 
      break loop 
     case html.TextToken: 
      fmt.Println(tt) 
     case html.StartTagToken: 
      t := htmlTokens.Token() 
      isAnchor := t.Data == "a" 
      if isAnchor { 
       fmt.Println("We found an anchor!") 
      } 
     } 
    } 
+0

고맙습니다.이 문제가 해결되어서 연결 누설조차 알지 못했습니다. 나는 아주 분명히 가야만한다. – King

+0

그건 내가 실제로 한 일이다. 그래도 고마워, 충고! – King