Библиотека

Как соскребать данные из Web с помощью Golang 2025

Вытаскивание данных из Интернета с помощью go

Веб-скрепинг - это мощная техника извлечения данных с веб-сайтов, и Golang (Go) - отличный язык для решения этой задачи. Известный своей производительностью и эффективностью, Go может с легкостью справиться с веб-скраппингом. Итак, как извлечь данные из Интернета с помощью Golang? В этом руководстве мы расскажем вам о том, как с помощью языка Golang можно скрапировать веб-страницы, а также о соответствующих техниках и советах.

Подходит ли Golang для сбора данных из Интернета?

Прежде чем узнать больше о том, как собирать данные из Интернета с помощью Golang, важно понять, почему для веб-скрапинга стоит выбрать именно Golang и какие преимущества он дает.

Golang - отличный выбор для веб-скрапинга благодаря высокой производительности, эффективной модели параллелизма и надежной стандартной библиотеке. Благодаря возможности одновременной обработки нескольких запросов с помощью goroutines и встроенным пакетам для HTTP-запросов и разбора HTML, Go может эффективно скрапировать большие объемы данных. Его простота и возможности обработки ошибок еще больше упрощают процесс разработки, а сторонние библиотеки, такие как Colly и Goquery, предлагают дополнительную функциональность. Хотя Go не так распространен, как Python, для веб-скрапинга, его преимущества делают его привлекательным вариантом для тех, кто знаком с этим языком.

Базовая конфигурация для соскабливания веб-данных с помощью Golang

Скраппинг данных из Интернета с помощью Go (Golang) заключается в выполнении HTTP-запросов для получения веб-страниц и последующем разборе HTML-содержимого для извлечения нужной информации. Ниже приведено пошаговое руководство по извлечению данных из Интернета с помощью Go:

    1. Настройка среды

      Сначала убедитесь, что Go установлена в вашей системе. Люди не могут скачать его с сайта официальный сайт.

      golang
    2. Установка необходимых пакетов

      Несколько пакетов необходимы для работы с HTTP-запросами и разбором HTML. Наиболее популярными пакетами являются net/http для HTTP-запросов и goquery для разбора HTML.

      Получите конкретный пакет, выполнив команду like:

      получить github.com/PuerkitoBio/goquery

      Написание скребка

      Вот простой пример, демонстрирующий, как с помощью Golang соскрести данные с веб-сайта:

      основной пакет
      
      импорт (
          "fmt"
          "log"
          "net/http"
      
          "github.com/PuerkitoBio/goquery"
      )
      
      func main() {
          // URL-адрес сайта, с которого будет производиться поиск
          url := "https://example.com"
      
          // Выполняем HTTP GET запрос
          res, err := http.Get(url)
          if err != nil {
              log.Fatal(err)
          }
          defer res.Body.Close()
      
          // Проверьте код состояния ответа
          if res.StatusCode != 200 {
              log.Fatalf("Failed to fetch data: %d %s", res.StatusCode, res.Status)
          }
      
          // Разбор HTML
          doc, err := goquery.NewDocumentFromReader(res.Body)
          if err != nil {
              log.Fatal(err)
          }
      
          // Найдите и распечатайте данные
          doc.Find("h1").Each(func(index int, item *goquery.Selection) {
              заголовок := item.Text()
              fmt.Println(heading)
          })
      }

      Выполнение HTTP-запросов:

      http.Get(url) выполняет HTTP GET-запрос к указанному URL.
      res.Body.Close() гарантирует, что тело ответа будет закрыто после прочтения.

      Разбор HTML:

      goquery.NewDocumentFromReader(res.Body) разбирает HTML-ответ и возвращает объект goquery.Document.

      Извлечение данных:

      doc.Find("h1").Each() находит все элементы h1 в HTML и выполняет итерацию по ним.
      item.Text() извлекает текстовое содержимое каждого элемента h1.

    3. Запуск скребка

      Сохраните приведенный выше код в файле, например, main.go, и запустите его с помощью:

      go run main.go

Дополнительные соображения

Обработка ошибок: Всегда обрабатывайте ошибки должным образом, чтобы не допустить неожиданного падения вашего скрепера.

С уважением robots.txt: Проверьте файл robots.txt сайта, чтобы убедиться, что вам разрешено его скрести.

Ограничение скорости: Установите ограничение скорости, чтобы не перегружать сервер запросами.

User-Agent: Установите пользовательский заголовок User-Agent для идентификации вашего скрепера, например:

req, err := http.NewRequest("GET", url, nil)
if err != nil {
    log.Fatal(err)
}
req.Header.Set("User-Agent", "Golang_Scraper/1.0")

client := &http.Client{}
res, err := client.Do(req)
if err != nil {
    log.Fatal(err)
}
defer res.Body.Close()

// Разбор HTML, как и раньше

Продвинутые техники соскабливания веб-данных с помощью Golang

Работа с пагинацией

Многие веб-сайты используют пагинацию для разделения содержимого на несколько страниц. Чтобы собрать все данные, вам нужно обработать пагинацию, последовательно выполняя запросы к каждой странице.

Вот пример работы с пагинацией:

основной пакет

импорт (
    "fmt"
    "log"
    "net/http"
    "strconv"

    "github.com/PuerkitoBio/goquery"
)

func main() {
    baseURL := "https://example.com/page/"
    страница := 1

    для {
        url := baseURL + strconv.Itoa(page)
        res, err := http.Get(url)
        if err != nil {
            log.Fatal(err)
        }
        defer res.Body.Close()

        if res.StatusCode != 200 {
            log.Println("Больше нет страниц для выборки, останавливаемся.")
            break
        }

        doc, err := goquery.NewDocumentFromReader(res.Body)
        if err != nil {
            log.Fatal(err)
        }

        doc.Find(".item").Each(func(index int, item *goquery.Selection) {
            title := item.Find(".title").Text()
            fmt.Println(title)
        })

        page++
    }
}

Работа с рендеринговым содержимым JavaScript

Некоторые веб-сайты используют JavaScript для динамического отображения содержимого. В Go нет встроенного способа выполнения JavaScript, но вы можете использовать безголовый браузер как Хромированный.

go get -u github.com/chromedp/chromedp

Пример использования Chromedp для поиска JavaScript-рендеринга:

основной пакет

импорт (
    "контекст"
    "fmt"
    "log"

    "github.com/chromedp/chromedp"
)

func main() {
    ctx, cancel := chromedp.NewContext(context.Background())
    отложить cancel()

    var htmlContent string

    err := chromedp.Run(ctx,
        chromedp.Navigate("https://example.com"),
        chromedp.OuterHTML("body", &htmlContent),
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(htmlContent)
}

Управление сеансами и файлами cookie

Если сайт требует входа в систему или управления сеансами, вы можете обрабатывать файлы cookie и сеансы с помощью http.CookieJar.

Пример управления файлами cookie:

основной пакет

импорт (
    "fmt"
    "log"
    "net/http"
    "net/http/cookiejar"

    "github.com/PuerkitoBio/goquery"
)

func main() {
    jar, _ := cookiejar.New(nil)
    client := &http.Client{Jar: jar}

    // Вход в систему и сохранение куки
    loginURL := "https://example.com/login"
    loginForm := url.Values{}
    loginForm.Set("имя пользователя", "ваше_имя")
    loginForm.Set("пароль", "ваш_пароль")

    res, err := client.PostForm(loginURL, loginForm)
    if err != nil {
        log.Fatal(err)
    }
    res.Body.Close()

    // Доступ к защищенной странице
    url := "https://example.com/protected-page"
    res, err = client.Get(url)
    if err != nil {
        log.Fatal(err)
    }
    отложить res.Body.Close()

    doc, err := goquery.NewDocumentFromReader(res.Body)
    if err != nil {
        log.Fatal(err)
    }

    doc.Find(".protected-content").Each(func(index int, item *goquery.Selection) {
        content := item.Text()
        fmt.Println(content)
    })
}

Дросселирование и ограничение скорости

Чтобы избежать блокировки сайтами, используйте ограничение скорости, вводя задержки между запросами.

Пример ограничения скорости:

основной пакет

импорт (
    "fmt"
    "log"
    "net/http"
    "время"

    "github.com/PuerkitoBio/goquery"
)

func main() {
    urls := []string{"https://example.com/page1", "https://example.com/page2"}

    for _, url := range urls {
        res, err := http.Get(url)
        if err != nil {
            log.Fatal(err)
        }
        defer res.Body.Close()

        doc, err := goquery.NewDocumentFromReader(res.Body)
        if err != nil {
            log.Fatal(err)
        }

        doc.Find(".item").Each(func(index int, item *goquery.Selection) {
            title := item.Find(".title").Text()
            fmt.Println(title)
        })

        // Задержка, чтобы избежать блокировки
        time.Sleep(2 * time.Second)
    }
}

Обработка запросов AJAX

Некоторые веб-сайты загружают данные динамически с помощью запросов AJAX. Вы можете перехватить и воспроизвести эти запросы, используя такие инструменты, как инструменты разработчика браузера, чтобы найти конечные точки API.

Пример получения данных из конечной точки AJAX API:

основной пакет

импорт (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

type Item struct {
    Title string `json: "title"`.
}

func main() {
    url := "https://example.com/api/items"

    res, err := http.Get(url)
    if err != nil {
        log.Fatal(err)
    }
    отложить res.Body.Close()

    var items []Item
    if err := json.NewDecoder(res.Body).Decode(&items); err != nil {
        log.Fatal(err)
    }

    for _, item := range items {
        fmt.Println(item.Title)
    }
}

Работа с капчами и механизмами защиты от кражи

На веб-сайтах часто используются CAPTCHA и другие механизмы защиты от подбора. Хотя программная разгадка CAPTCHA сложна и часто противоречит условиям предоставления услуг, вы можете использовать такие приемы, как ротация пользователей-агентов и прокси-серверы, чтобы избежать обнаружения.

Пример вращающихся агентов пользователя:

основной пакет

импорт (
    "fmt"
    "log"
    "net/http"
    "math/rand"
    "время"
)

func main() {
    userAgents := []string{
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, как Gecko) Chrome/58.0.3029.110 Safari/537.3",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:54.0) Gecko/20100101 Firefox/54.0",
        // Добавьте сюда другие агенты пользователя
    }

    client := &http.Client{}
    rand.Seed(time.Now().UnixNano())

    for i := 0; i < 5; i++ {
        req, err := http.NewRequest("GET", "https://example.com", nil)
        if err != nil {
            log.Fatal(err)
        }

        req.Header.Set("User-Agent", userAgents[rand.Intn(len(userAgents))])
        res, err := client.Do(req)
        if err != nil {
            log.Fatal(err)
        }
        res.Body.Close()

        fmt.Println("Запрос отправлен с user-agent:", req.Header.Get("User-Agent"))
    }
}

Использование прокси-серверов

Чтобы дополнительно защитить свой IP от запрета, вы можете использовать прокси-серверы. Такие сервисы, как OkeyProxy или MacroProxy, предоставляют прокси-решения.

Являясь одним из лучших прокси-провайдеров, OkeyProxy поддерживается HTTP/HTTPS/SOCKS и предоставляет 150 миллионов с лишним реальных IP-адресов, охватывающих 200 с лишним стран/регионов, что позволяет избежать Запрет IP-адресов максимально возможной степени и обеспечивает безопасность, надежность и стабильность сетевых соединений.

okeyproxy

Пример использования прокси с http.Client:

основной пакет

импорт (
    "fmt"
    "log"
    "net/http"
    "net/url"
)

func main() {
    proxyURL, _ := url.Parse("http://proxyusername:proxypassword@proxyserver:port")
    transport := &http.Transport{
        Proxy: http.ProxyURL(proxyURL),
    }

    client := &http.Client{Transport: transport}

    res, err := client.Get("https://example.com")
    if err != nil {
        log.Fatal(err)
    }
    отложить res.Body.Close()

    fmt.Println("Статус ответа:", res.Status)
}

Одновременное скрапирование

Чтобы ускорить работу со скрапом, вы можете использовать гортины для одновременной обработки нескольких запросов. Это удобно при работе с большими наборами данных.

Пример одновременного скраппинга с помощью goroutines:

основной пакет

импорт (
    "fmt"
    "log"
    "net/http"
    "sync"

    "github.com/PuerkitoBio/goquery"
)

func scrape(url string, wg *sync.WaitGroup) {
    отложить wg.Done()

    res, err := http.Get(url)
    if err != nil {
        log.Println(err)
        return
    }
    defer res.Body.Close()

    doc, err := goquery.NewDocumentFromReader(res.Body)
    if err != nil {
        log.Println(err)
        return
    }

    doc.Find(".item").Each(func(index int, item *goquery.Selection) {
        title := item.Find(".title").Text()
        fmt.Println(title)
    })
}

func main() {
    urls := []string{
        "https://example.com/page1",
        "https://example.com/page2",
        // Добавьте другие URL-адреса
    }

    var wg sync.WaitGroup

    for _, url := range urls {
        wg.Add(1)
        go scrape(url, &wg)
    }

    wg.Wait()
}

Сбор данных из API

Многие веб-сайты предлагают API для доступа к данным. Использовать API часто проще и эффективнее, чем скрести HTML.

Пример вызова API:

основной пакет

импорт (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

func main() {
    url := "https://api.example.com/data"

    res, err := http.Get(url)
    if err != nil {
        log.Fatal(err)
    }
    отложить res.Body.Close()

    var data map[string]interface{}
    if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
        log.Fatal(err)
    }

    fmt.Println("Данные API:", data)
}

Хранение данных

В зависимости от ваших требований, вам может понадобиться хранить собранные данные в базе данных или в файле. Вот пример записи данных в файл CSV:

основной пакет

импорт (
    "encoding/csv"
    "fmt"
    "log"
    "os"
    "net/http"
    "github.com/PuerkitoBio/goquery"
)

func main() {
    file, err := os.Create("data.csv")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    writer := csv.NewWriter(file)
    defer writer.Flush()

    urls := []string{"https://example.com/page1", "https://example.com/page2"}

    for _, url := range urls {
        res, err := http.Get(url)
        if err != nil {
            log.Fatal(err)
        }
        defer res.Body.Close()

        doc, err := goquery.NewDocumentFromReader(res.Body)
        if err != nil {
            log.Fatal(err)
        }

        doc.Find(".item").Each(func(index int, item *goquery.Selection) {
            title := item.Find(".title").Text()
            writer.Write([]string{title})
        })
    }

    fmt.Println("Данные записаны в файл data.csv")
}

Обработка ошибок и ведение журнала

Надежная обработка ошибок и протоколирование очень важны для устранения неполадок и поддержки скреперов. Вы можете использовать возможности протоколирования в Go или внешние библиотеки, такие как logrus, для расширенного протоколирования.

Основные библиотеки для веб-скрапинга на Golang

  1. Колли:Мощный и простой в использовании фреймворк для веб-скрепинга.Установка: go get -u github.com/gocolly/colly
  2. GoqueryjQuery-подобная библиотека для манипулирования и запроса HTML.Установка: go get -u github.com/PuerkitoBio/goquery
  3. Запрос:Упрощенный HTTP-клиент для выполнения запросов.Установка: go get -u github.com/imroc/req
  4. Grequests:Библиотека HTTP-запросов более высокого уровня, аналогичная Python'овской Requests.Установка: go get -u github.com/levigross/grequests
  5. ХромированныйАвтоматизация браузера с помощью протокола Chrome DevTools Protocol.Установка: go get -u github.com/chromedp/chromedp
  6. Род:Современная библиотека автоматизации браузеров для Go, с акцентом на простоту использования и современные возможности.Установка: go get -u github.com/ysmood/rod
  7. Go-Selenium:Клиент Selenium WebDriver для Go, полезный для автоматизации работы браузеров.Установка: go get -u github.com/tebeka/selenium
  8. СколлиОбертка вокруг Colly для упрощенного веб-скрепинга.Установка: go get -u github.com/scolly/scolly
  9. Бровь нараспашкуGo-клиент для API Browshot, позволяющий делать скриншоты и скрести контент с веб-страниц.Установка: go get -u github.com/browshot/browshot-go
  10. Кукловод -:Go-порт Puppeteer, библиотеки Node для управления безголовым Chrome.Установка: go get -u github.com/chromedp/puppeteer-go
  11. Go-requests:Простая библиотека HTTP-запросов, созданная на основе Python's Requests.Установка: go get -u github.com/deckarep/golang-set
  12. Httpproxy:Простой HTTP-прокси-сервер для Go, полезный для маршрутизации веб-трафика для скрапбукинга.Установка: go get -u github.com/henrylee2cn/httpproxy
  13. Ползание:Библиотека для создания распределенных веб-краулеров.Установка: go get -u github.com/whyrusleeping/crawling
  14. K6Хотя K6 в первую очередь является инструментом для нагрузочного тестирования, его можно использовать для сбора веб-данных с помощью скриптов.Установка: go get -u github.com/loadimpact/k6
  15. Net/http:Стандартная библиотека для выполнения HTTP-запросов в Go.Установка: Встроена в Go, не требует отдельной установки.
  16. Goquery-html:Еще одна библиотека для разбора HTML с улучшениями на основе Goquery.Установка: go get -u github.com/PuerkitoBio/goquery-html
  17. Httpclient:Высокоуровневый HTTP-клиент для Go, предлагающий расширенные возможности запросов.Установка: go get -u github.com/aymerick/raymond

Эти библиотеки и инструменты охватывают широкий спектр функций, от простых HTTP-запросов до полной автоматизации браузера, что делает их универсальными для различных задач веб-скрепинга.

Резюме

Извлечение данных из Интернета с помощью Golang имеет ряд преимуществ, включая эффективность производительности и простоту параллелизма. Легкие горутины и каналы Go позволяют обрабатывать несколько одновременных запросов с минимальными затратами ресурсов, что делает его идеальным для решения масштабных задач извлечения данных. Кроме того, сильная стандартная библиотека Go поддерживает надежные возможности разбора HTTP и HTML, что упрощает разработку эффективных и надежных приложений для веб-скрепинга. Такое сочетание скорости, параллелизма и встроенных инструментов делает Golang привлекательным выбором для проектов веб-скрепинга, требующих высокой производительности и масштабируемости.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

ТОП
Перевод >>