2016-10-09 6 views
1

Я сейчас пытаюсь работать с токенизатором html https://godoc.org/golang.org/x/net/html.«Бесконечный цикл», вызывающий недостижимый код

Так что я хочу сделать следующее: получить все ссылки с url и если url содержит определенную строку -> add to url-list.

resp, err = client.Get("someurl") 
var urls []string 

if err != nil { 
    log.Fatal(err) 
} 

z := html.NewTokenizer(resp.Body) 

for { 
    tt := z.Next() 

    switch { 
    case tt == html.ErrorToken: 
     return 
    case tt == html.StartTagToken: 
     t := z.Token() 

     isAnchor := t.Data == "a" 
     if !isAnchor { 
      continue 
     } 

     ok, url := getHref(t) 
     if !ok { 
      continue 
     } 
     if strings.Contains(url, "somestring") { 
      urls = append(urls, url) 
     } 

    } 
} 

fmt.Println(urls) 

Это не работает, так как «fmt.Println (urls)» недоступен. Цикл c заканчивается в какой-то момент .... но это не компилируется. Как получить код после того, как цикл будет доступен?

С уважением

ответ

1

Там нет в цикле нет break. Единственный способ, которым он заканчивается, - это использовать return, который отправляет управление из этой функции. Это означает, что fmt.Println(urls) недоступен.

Попробуйте это:

L: 
for { 
    tt := z.Next() 

    switch { 
    case tt == html.ErrorToken: 
     break L 
    case tt == html.StartTagToken: 
     t := z.Token() 

     isAnchor := t.Data == "a" 
     if !isAnchor { 
      continue 
     } 

     ok, url := getHref(t) 
     if !ok { 
      continue 
     } 
     if strings.Contains(url, "somestring") { 
      urls = append(urls, url) 
     } 

    } 
} 
+0

это работает как шарм! Спасибо. –

1

Используйте пример они предусмотрены здесь: https://godoc.org/golang.org/x/net/html#example-Parse

изменить код, чтобы соответствовать следующим образом:

resp, err = client.Get("someurl") 
var urls []string 

if err != nil { 
    log.Fatal(err) 
} 

doc, err := html.Parse(strings.NewReader(resp.Body)) 
if err != nil { 
    log.Fatal(err) 
} 

var f func(*html.Node) 
f = func(n *html.Node) { 
    if n.Type == html.ElementNode && n.Data == "a" { 
     for _, a := range n.Attr { 
      if a.Key == "href" { 
       fmt.Println(a.Val) 

       if strings.Contains(a.Val, "somestring") { 
        urls = append(urls, a.Val) 
       } 

       break 
      } 
     } 
    } 
    for c := n.FirstChild; c != nil; c = c.NextSibling { 
     f(c) 
    } 
} 
f(doc) 
Смежные вопросы