Поделитесь волной поисковых роботов GO

задняя часть
Поделитесь волной поисковых роботов GO

Это первый раз, когда я участвую в Gengwen Challenge.23День, подробности о событии уточняйте:Обновить вызов

Поделитесь волной поисковых роботов GO

Давайте рассмотрим то, что мы сказали в прошлый разОтправить письмо с GOLANG

Golang+chromedp+goquery Простое сканирование динамических данных |Go Theme Month

  • Совместное использование электронной почты, что такое электронная почта?
  • Какие есть почтовые протоколы
  • КАК ОТПРАВИТЬ ПОЧТУ С GOLANG
  • как отправить электронное письмо с простым текстом,HTMLсодержание, вложения и т. д.
  • отправить письмо, как сделать копию, как сделать скрытую копию
  • Как повысить эффективность отправки писем

хочу увидетьКак отправить почту с GOLANGДа, добро пожаловать на просмотр статьиКак отправить почту с GOLANG

Помните, что мы кратко поделились статьей о сканировании динамических данных веб-страниц с помощью golang перед тем, какGolang+chromedp+goquery Простое сканирование динамических данных |Go Theme Month

Если кому интересно, можем подробно изучитьструктура chromedpкак использовать

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

Что такое статические веб-страницы и динамические веб-страницы?

Что такое статические веб-данные?

  • Это означает, что на веб-странице нет программного кода, толькоHTML, то есть только язык гипертекстовой разметки, суффикс вообще.html , htm , xmlтак далее
  • Еще одна особенность статических веб-страниц заключается в том, что пользователи могут щелкнуть, чтобы открыть их напрямую, а содержимое страниц, которое кто-либо открывает в любое время, остается неизменным.htmlКод исправлен, эффект исправлен

Кстати, что такое динамическая веб-страница?

  • Динамическая веб-страница — это технология веб-программирования.

    В дополнение к файлу веб-страницы динамических веб-страницHTMLПомимо знака, он также включает в себя некоторый программный код для определенных функций.

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

То есть, хотя код страницы динамической веб-страницы не изменился, отображаемый контент может меняться с течением времени, в различных средах и изменениях в базе данных.

GO для сканирования статических данных веб-страниц

Мы сканируем данные статических веб-страниц, например, мы сканируем статические данные на этом веб-сайте и сканируем информацию об учетной записи и пароле на веб-странице.

http://www.ucbug.com/jiaocheng/63149.html?_t=1582307696

Шаги, которые мы предпринимаем для сканирования этого веб-сайта:

  • Укажите веб-сайт, который явно необходимо сканировать
  • пройти черезHTTP GETспособ получить данные
  • Преобразование строки символов в байтовый массив
  • Используйте регулярные выражения, чтобы соответствовать тому, что мы ожидаем (Это очень важно, ведь сканирование статических веб-страниц, обработка и фильтрация данных занимает много времени.)
  • Проверка данных, дедупликация и другие операции (этот шаг варьируется от человека к человеку и целевому веб-сайту в соответствии с индивидуальными потребностями)

Давайте напишем DEMO, поднимемся по указанному выше URLИнформация об учетной записи и пароле, информация, которую мы хотим разместить на веб-странице, подобна этой, мы предназначены только для изучения и использования, не используйте ее для совершения каких-либо плохих действий.

package main

import (
   "io/ioutil"
   "log"
   "net/http"
   "regexp"
)

const (
   // 正则表达式,匹配出 XL 的账号密码
   reAccount = `(账号|迅雷账号)(;|:)[0-9:]+(| )密码:[0-9a-zA-Z]+`
)

// 获取网站 账号密码
func GetAccountAndPwd(url string) {
   // 获取网站数据
   resp, err := http.Get(url)
   if err !=nil{
      log.Fatal("http.Get error : ",err)
   }
   defer resp.Body.Close()

   // 去读数据内容为 bytes
   dataBytes, err := ioutil.ReadAll(resp.Body)
   if err !=nil{
      log.Fatal("ioutil.ReadAll error : ",err)
   }

   // 字节数组 转换成 字符串
   str := string(dataBytes)

   // 过滤 XL 账号和密码
   re := regexp.MustCompile(reAccount)

   // 匹配多少次, -1 默认是全部
   results := re.FindAllStringSubmatch(str, -1)

   // 输出结果
   for _, result := range results {
      log.Println(result[0])
   }
}

func main() {
   // 简单设置log 参数
   log.SetFlags(log.Lshortfile | log.LstdFlags)
   // 传入网站地址,爬取开始爬取数据
   GetAccountAndPwd("http://www.ucbug.com/jiaocheng/63149.html?_t=1582307696")
}

Результат выполнения приведенного выше кода выглядит следующим образом:

2021/06/xx xx:05:25 main.go:46: 账号:357451317 密码:110120a
2021/06/xx xx:05:25 main.go:46: 账号:907812219 密码:810303
2021/06/xx xx:05:25 main.go:46: 账号:797169897 密码:zxcvbnm132
2021/06/xx xx:05:25 main.go:46: 迅雷账号:792253782:1密码:283999
2021/06/xx xx:05:25 main.go:46: 迅雷账号:147643189:2密码:344867
2021/06/xx xx:05:25 main.go:46: 迅雷账号:147643189:1密码:267297

Как можно заметить,账号:Данные, начинающиеся с и迅雷账号:Данные в начале были просканированы нами, на самом деле просканировать содержимое статических веб-страниц несложно.Время в основном тратится на сопоставление регулярных выражений и обработку данных.

В соответствии с приведенными выше шагами сканирования веб-страниц мы можем перечислить:

  • посетите вебсайтhttp.Get(url)
  • читать содержимое данныхioutil.ReadAll
  • преобразовать данные в строку
  • Установите правила для регулярного сопоставленияregexp.MustCompile(reAccount)
  • Начните фильтровать данные, вы можете установить количество фильтровre.FindAllStringSubmatch(str, -1)

Конечно, на практике это точно не так просто.

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

Тем не менее, вышеуказанные проблемы могут быть решены.В соответствии с различными проблемами, разработаны различные решения и обработка данных.Я считаю, что друзья, которые сталкиваются с этим, смогут решить его.Столкнувшись с проблемами, мы должны иметь решимость их решить.

Сканировать картинки

Прочитав приведенный выше пример, давайте попробуем просканировать данные изображения на веб-странице, например, выполнить поиск по определенной степени.柴犬

такая страница

давайте положимurlАдресная строкаurlСкопируйте и вставьте его для сканирования данных

https://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=%E6%9F%B4%E7%8A%AC

Поскольку есть много фотографий, мы устанавливаем только соответствие2данные изображения

Давайте посмотрим на DEMO вместе

  • КстатиGet urlданные и преобразовать их в строковую функцию, извлечь их и инкапсулировать в небольшую функцию
  • GetPic,Специально используйте регулярные выражения для сопоставления, вы можете установить количество совпадений, мы установим совпадение здесь2второсортный
package main

import (
   "io/ioutil"
   "log"
   "net/http"
   "regexp"
)

const (
   // 正则表达式,匹配出XL的账号密码
   reAccount = `(账号|迅雷账号)(;|:)[0-9:]+(| )密码:[0-9a-zA-Z]+`
   // 正则表达式,匹配出 图片
   rePic = `https?://[^"]+?(\.((jpg)|(png)|(jpeg)|(gif)|(bmp)))`
)

func getStr(url string)string{
   resp, err := http.Get(url)
   if err !=nil{
      log.Fatal("http.Get error : ",err)
   }
   defer resp.Body.Close()

   // 去读数据内容为 bytes
   dataBytes, err := ioutil.ReadAll(resp.Body)
   if err !=nil{
      log.Fatal("ioutil.ReadAll error : ",err)
   }

   // 字节数组 转换成 字符串
   str := string(dataBytes)
   return str
}

// 获取网站 账号密码
func GetAccountAndPwd(url string,n int) {
   str := getStr(url)
   // 过滤 XL 账号和密码
   re := regexp.MustCompile(reAccount)

   // 匹配多少次, -1 默认是全部
   results := re.FindAllStringSubmatch(str, n)

   // 输出结果
   for _, result := range results {
      log.Println(result[0])
   }
}

// 获取网站 账号密码
func GetPic(url string,n int) {

   str := getStr(url)

   // 过滤 图片
   re := regexp.MustCompile(rePic)

   // 匹配多少次, -1 默认是全部
   results := re.FindAllStringSubmatch(str, n)

   // 输出结果
   for _, result := range results {
      log.Println(result[0])
   }
}


func main() {
   // 简单设置l og 参数
   log.SetFlags(log.Lshortfile | log.LstdFlags)
   //GetAccountAndPwd("http://www.ucbug.com/jiaocheng/63149.html?_t=1582307696", -1)
   GetPic("https://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=%E6%9F%B4%E7%8A%AC",2)
}

Запустив приведенный выше код, результат будет следующим (без дедупликации):

2021/06/xx xx:06:39 main.go:63: https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4246005838,1103140037&fm=26&gp=0.jpg
2021/06/xx xx:06:39 main.go:63: https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4246005838,1103140037&fm=26&gp=0.jpg

Конечно, это то, что нам нужно, но просто распечатать и сканировать — это все ссылки на изображения, которые определенно не могут удовлетворить потребности наших настоящих краулеров.

Для удобства демонстрации добавим на приведенный выше код небольшую функцию скачивания файлов, и будем скачивать первую

package main

import (
   "fmt"
   "io/ioutil"
   "log"
   "net/http"
   "regexp"
   "strings"
   "time"
)

const (
   // 正则表达式,匹配出 图片
   rePic = `https?://[^"]+?(\.((jpg)|(png)|(jpeg)|(gif)|(bmp)))`
)

// 获取网页数据,且把数据转成 字符串
func getStr(url string) string {
   resp, err := http.Get(url)
   if err != nil {
      log.Fatal("http.Get error : ", err)
   }
   defer resp.Body.Close()

   // 去读数据内容为 bytes
   dataBytes, err := ioutil.ReadAll(resp.Body)
   if err != nil {
      log.Fatal("ioutil.ReadAll error : ", err)
   }

   // 字节数组 转换成 字符串
   str := string(dataBytes)
   return str
}

// 获取图片数据
func GetPic(url string, n int) {

   str := getStr(url)

   // 过滤 图片
   re := regexp.MustCompile(rePic)

   // 匹配多少次, -1 默认是全部
   results := re.FindAllStringSubmatch(str, n)

   // 输出结果
   for _, result := range results {
      // 获取具体的图片名字
      fileName := GetFilename(result[0])
	 // 下载图片
      DownloadPic(result[0], fileName)
   }
}

// 获取到 文件的 名字
func GetFilename(url string) (filename string) {
   // 找到最后一个 = 的索引
   lastIndex := strings.LastIndex(url, "=")
   // 获取 / 后的字符串 ,这就是源文件名
   filename = url[lastIndex+1:]

   // 把时间戳 加 在原来名字前,拼一个新的名字
   prefix := fmt.Sprintf("%d",time.Now().Unix())
   filename = prefix + "_" + filename

   return filename
}

func DownloadPic(url string, filename string) {
   resp, err := http.Get(url)
   if err != nil {
      log.Fatal("http.Get error : ", err)
   }
   defer resp.Body.Close()

   bytes, err := ioutil.ReadAll(resp.Body)
   if err != nil {
      log.Fatal("ioutil.ReadAll error : ", err)
   }

   // 文件存放的路径
   filename = "./" + filename

   // 写文件 并设置文件权限
   err = ioutil.WriteFile(filename, bytes, 0666)
   if err != nil {
      log.Fatal("wirte failed !!", err)
   } else {
      log.Println("ioutil.WriteFile successfully , filename = ", filename)
   }
}

func main() {
   // 简单设置l og 参数
   log.SetFlags(log.Lshortfile | log.LstdFlags)
   GetPic("https://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=%E6%9F%B4%E7%8A%AC", 1)
}

Приведенный выше код мы добавили2Функция, которая поможет нам изменить имя изображения и загрузить изображение.

  • Получите имя файла и переименуйте его с отметкой времени,GetFilename
  • Загрузите конкретное изображение и загрузите его в текущий каталог,DownloadPic

Запустив приведенный выше код, вы можете увидеть следующий эффект

2021/06/xx xx:50:04 main.go:91: ioutil.WriteFile successfully , filename =  ./1624377003_0.jpg

И в текущем каталоге успешно скачана картинка, название1624377003_0.jpg

Ниже приведено изображение конкретной картины

Некоторые старшие братья скажут, что мне слишком медленно загружать изображения с помощью одной сопрограммы, можете ли вы загрузить ее быстрее и загрузить несколько сопрограмм вместе?

Одновременное ползание нашего сиба-ину

Давайте вспомним, что мы говорили раньшеКанал GO и пакет синхронизации?Совместное использование каналов GO и пакетов синхронизации, просто для практики, эта небольшая функция относительно проста, расскажите мне общую идею, если вам интересно, вы можете реализовать волну,

  • Мы читаем данные вышеуказанного URL и преобразуем их в строку
  • Используйте обычное сопоставление, чтобы сопоставить серию соответствующих ссылок на изображения.
  • Поместите каждую ссылку на изображение в буферизованный канал, временно установите буфер на 100
  • Давайте откроем 3 сопрограммы, чтобы одновременно читать данные канала и загружать их на локальный.Метод модификации имени файла может ссылаться на приведенный выше код.

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

Суммировать

  • Краткая инструкция по обмену статическими и динамическими веб-страницами
  • GO сканирует простые данные со статических веб-страниц
  • GO сканирует изображения в Интернете
  • Одновременно сканировать ресурсы в Интернете

Добро пожаловать лайк, подписка, избранное

Друзья, ваша поддержка и поощрение мотивируют меня продолжать делиться и улучшать качество.

Хорошо, вот и на этот раз,Очередное приложение и обмен gjson в GO

Технологии открыты, и наш менталитет должен быть открытым. Примите перемены, живите на солнце и двигайтесь вперед.

ямаленький дьяволенок Нежа, добро пожаловать, лайкайте, подписывайтесь и добавляйте в избранное, увидимся в следующий раз~