>  기사  >  백엔드 개발  >  golang은 크롤러를 지시하지 않습니다

golang은 크롤러를 지시하지 않습니다

PHPz
PHPz원래의
2023-05-10 10:06:06435검색

1. 소개

인터넷의 발달로 웹 크롤러의 적용 범위가 점점 넓어지고 있습니다. 일상생활에서는 뉴스, 주식, 날씨, 영화, 음악 등 다양한 정보를 웹 크롤러를 통해 얻을 수 있습니다. 특히 빅데이터 분석과 인공지능 분야에서는 웹 크롤러가 중요한 역할을 한다. 이 기사에서는 인터넷에서 정보를 얻기 위해 golang 언어를 사용하여 무방향(즉, 특정 대상 웹사이트가 아닌) 크롤러를 작성하는 방법을 주로 설명합니다.

2. golang 소개

Golang은 동시성, 고성능, 단순성 및 학습 용이성으로 인해 Google에서 개발한 프로그래밍 언어입니다. 이 글에서 사용된 golang 버전은 1.14.2입니다.

3. 구현 아이디어

이 크롤러는 주로 다음 단계로 나뉩니다.

  1. 시작 URL 가져오기

수동으로 URL을 입력하고, 파일에서 URL을 읽고, 데이터베이스 등 시작 URL.

  1. Send http request

Get 또는 Post를 통해 http 요청을 보내 응답 데이터를 가져옵니다.

  1. 응답 데이터 구문 분석

정규 표현식이나 타사 라이브러리를 사용하여 응답 데이터 형식에 따라 데이터를 구문 분석하세요.

  1. 데이터 저장

필요에 따라 데이터를 파일이나 데이터베이스에 저장하거나 다른 저장 방법을 사용할 수 있습니다.

  1. 새 URL을 구문 분석합니다

응답 데이터의 하이퍼링크 및 기타 정보에 따라 새 URL을 크롤링할 다음 URL로 구문 분석합니다.

  1. 위 단계를 반복하세요

새 URL에 따라 다시 http 요청을 보내고, 응답 데이터를 구문 분석하고, 데이터를 저장하고, 새 URL을 구문 분석하고, 새 URL이 없을 때까지 반복합니다.

4. 코드 구현

golang에서는 net/http 패키지를 사용하여 http 요청을 보내고, regexp 패키지 또는 타사 라이브러리를 사용하여 응답 데이터를 구문 분석합니다.

  1. 초기화 함수

먼저 시작 URL 획득, http 클라이언트 설정 및 기타 작업을 담당하는 초기 함수를 정의해야 합니다.

func init() {
    // 获取起始网址
    flag.StringVar(&startUrl, "url", "", "请输入起始网址")
    flag.Parse()

    // 设置http客户端
    client = &http.Client{
        Timeout: 30 * time.Second,
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            return http.ErrUseLastResponse
        },
    }
}
  1. http 요청 보내기 기능

http 요청을 보내고 응답 데이터를 얻는 기능을 정의하세요.

func GetHtml(url string) (string, error) {
    resp, err := client.Get(url)
    if err != nil {
        log.Println(err)
        return "", err
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Println(err)
        return "", err
    }

    return string(body), nil
}
  1. 응답 데이터 함수 분석

goquery 라이브러리를 사용하여 응답 데이터를 구문 분석합니다. 구체적인 구현은 다음과 같습니다.

func ParseSingleHTML(html string, query string) []string {
    doc, err := goquery.NewDocumentFromReader(strings.NewReader(html))
    if err != nil {
        log.Println(err)
        return nil
    }

    result := make([]string, 0)
    doc.Find(query).Each(func(i int, selection *goquery.Selection) {
        href, ok := selection.Attr("href")
        if ok {
            result = append(result, href)
        }
    })

    return result
}
  1. 저장 데이터 함수

데이터를 파일에 저장하는 함수를 정의합니다.

func SaveData(data []string) error {
    file, err := os.OpenFile("data.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
    if err != nil {
        log.Println(err)
        return err
    }
    defer file.Close()

    writer := bufio.NewWriter(file)
    for _, line := range data {
        _, err := writer.WriteString(line + "
")
        if err != nil {
            log.Println(err)
            return err
        }
    }
    writer.Flush()

    return nil
}
  1. 새 URL 함수 구문 분석

정규 표현식을 사용하여 하이퍼링크의 새 URL을 구문 분석하세요.

func ParseHref(url, html string) []string {
    re := regexp.MustCompile(`<a[sS]+?href="(.*?)"[sS]*?>`)
    matches := re.FindAllStringSubmatch(html, -1)

    result := make([]string, 0)
    for _, match := range matches {
        href := match[1]
        if strings.HasPrefix(href, "//") {
            href = "http:" + href
        } else if strings.HasPrefix(href, "/") {
            href = strings.TrimSuffix(url, "/") + href
        } else if strings.HasPrefix(href, "http://") || strings.HasPrefix(href, "https://") {
            // do nothing
        } else {
            href = url + "/" + href
        }
        result = append(result, href)
    }

    return result
}
  1. Main function

마지막으로 전체 크롤러 프로세스를 구현하기 위한 Main 함수를 정의해야 합니다.

func main() {
    // 确认起始网址是否为空
    if startUrl == "" {
        fmt.Println("请指定起始网址")
        return
    }

    // 初始化待访问队列
    queue := list.New()
    queue.PushBack(startUrl)

    // 初始化已访问集合
    visited := make(map[string]bool)

    // 循环爬取
    for queue.Len() > 0 {
        // 从队列中弹出一个网址
        elem := queue.Front()
        queue.Remove(elem)
        url, ok := elem.Value.(string)
        if !ok {
            log.Println("网址格式错误")
            continue
        }

        // 确认该网址是否已经访问过
        if visited[url] {
            continue
        }
        visited[url] = true

        // 发送http请求,获取响应数据
        html, err := GetHtml(url)
        if err != nil {
            continue
        }

        // 解析响应数据,获取新的网址
        hrefs := ParseHref(url, html)
        queue.PushBackList(list.New().Init())
        for _, href := range hrefs {
            if !visited[href] {
                hrefHtml, err := GetHtml(href)
                if err != nil {
                    continue
                }
                hrefUrls := ParseSingleHTML(hrefHtml, "a")

                // 将新的网址加入队列
                queue.PushBackList(list.New().Init())
                for _, hrefUrl := range hrefUrls {
                    queue.PushBack(hrefUrl)
                }
            }
        }

        // 存储数据到文件
        data := ParseSingleHTML(html, "title")
        err = SaveData(data)
        if err != nil {
            continue
        }
    }
}

5. 요약

위는 golang을 사용하여 무방향 크롤러를 작성하는 기본 프로세스 및 구현 방법입니다. 물론 이는 단순한 예일 뿐이며 실제 개발에서는 크롤러 방지 전략, 스레드 안전성 및 기타 문제도 고려해야 합니다. 독자들에게 도움이 되기를 바랍니다.

위 내용은 golang은 크롤러를 지시하지 않습니다의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.