Перейти показы
Однажды в 2018 году я спросил бэкенд-архитектора компании, что хочу выучить язык бэкенда, кроме Java, он сказал мне, что изучает Go. Затем он рассказал мне о некоторых понятиях, таких как распределение, сопрограммы, большие данные, рептилии... понятия Барабалы, которые я не совсем понимаю. Тогда я сказал, что мне лучше изучить NodeJs.
Причина, по которой она снова осмелилась бороться с языком го, полностью связана с Лян Цзинру (последний призыв к бумагам) придало мне смелости. Если вы являетесь бэкэнд-боссом, просто прочитайте гусеничную часть второй половины.
Тема этой статьи — скорость, поисковые роботы и колонка Nuggets. Цель — использовать Go для написания небольшого инструмента, который будет сканировать колонку Nuggets и медленно читать ее.
Let's Go
Преимущество
- Простая грамматика и простота использования (всего 25 зарезервированных ключевых слов)
- Высокая производительность, быстрая компиляция и эффективность разработки не ниже Python и Ruby.
- Его легко развернуть, пакет компиляции небольшой, и почти нет зависимостей (пакет бинарных файлов можно запускать напрямую), что очень похоже на Deno.
- Встроенная поддержка параллелизма (горутина)
- Официальная унифицированная спецификация (gofmt, golint) снова увидела тень Deno
- Богатая стандартная библиотека, снова увидеть тень Deno
тренд
Авторитетный тренд, ваш дуговой босс, уже ясно дал понять, я добавлю сюда звездный тренд GitHub:
Введение в Го
Go — статически строго типизированный, скомпилированный параллельный язык программирования с функцией сборки мусора, разработанный Google. Иногда его называют Golang для простоты поиска и идентификации.
Особенности языка Go
- Go — это новый язык, статический язык, который поддерживает параллелизм, сборку мусора и быструю компиляцию.
- Go обеспечивает базовую поддержку параллельного выполнения и обмена данными и является естественным высокопроизводительным языком разработки сервисов.
- Go сочетает в себе простоту интерпретируемого языка, эффективность разработки языка с динамической типизацией и безопасность статической типизации.
- Go может скомпилировать большую программу Go за считанные секунды, а развертывание очень простое.
- Go обладает эффективностью разработки Python/Ruby и производительностью языка C (все еще существует определенный разрыв).
- Go легко выучить (всего 25 ключевых зарезервированных слов)
- Go имеет собственную спецификацию разработки, а также предоставляет инструментальную поддержку.
Перейти к настройке установки
у автора другаяСреда разработки программиста для Mac [постоянно обновляется], записал среду разработки на свой Mac, может кстати читатели дадут звезду?
$ brew install go
Совет 1:
ctrl+c
можно пропуститьUpdating Homebrew...
, иначе вы застрянете и будете сомневаться в своей жизни.
Совет 2: Если у вас есть время ждать, возьмите его с собой
-verbose
параметры, так что загрузка будет сообщать вам о ходе обновления.
Совет 3: Homebrew — это синхронизированный репозиторий GitHub.Если вы застряли, измените источник прокси-сервера Homebrew самостоятельно.
После успешной установки проверьте версию go:
$ go version
go version go1.14.7 darwin/amd64
Настройте переменные среды:
$ open /usr/local/Cellar/go/
Затем посмотрите, где находится ваш libexec, и запишите общий адрес.
/usr/local/Cellar/go/1.14.7/libexec
Эту часть нужно записатьnano ~/.zshrc
:
#GO
export GOROOT=/usr/local/Cellar/go/1.14.7/libexec
export GOPATH=~/.go
export PATH=${PATH}:$GOPATH/bin
не забудьте выполнить source ~/.zshrc
вступит в силу после команды. затем выполнитьgo env
Проверьте, успешно ли выполнена команда
Вывод слишком длинный, пожалуйста, нажмите, чтобы просмотреть! ! !
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/yangjunning/Library/Caches/go-build"
GOENV="/Users/yangjunning/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/yangjunning/go"
GOPRIVATE=""
GOPROXY="https://goproxy.cn,direct"
GOROOT="/usr/local/Cellar/go/1.14.7/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.14.7/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/zn/17xnqr8s1pjbpzt9_t38tyhc0000gn/T/go-build998676802=/tmp/go-build -gno-record-gcc-switches -fno-common"
Прокси-сервер Qiniu Cloud Mirror
Откройте свой терминал и выполните, Go 1.13 и выше возможны, другие версии, пожалуйста, прочитайтеGoproxy КитайПосмотреть документацию
$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,direct
Перейти общие команды
1,go build
: используется для компиляции исходных файлов или пакетов кода, которые мы указываем, и их зависимостей.
2,go clean
: используется для удаления скомпилированных файлов в текущем исходном пакете
3.go doc
: Распечатайте документацию, прикрепленную к программному объекту языка Go. Мы можем просмотреть его документацию, передав идентификатор программного объекта в качестве аргумента этой команде.
4.go fmt
: помогите отформатировать ваши файлы кода, вам просто нужно выполнить go fmt xxx.go ваш код будет изменен в стандартный формат
5.go get
: Загрузите или обновите указанные пакеты зависимостей на уровне кода из Интернета в соответствии с требованиями и фактическими условиями, а затем скомпилируйте и установите их.
6.go install
: используется для компиляции и установки указанных пакетов кода и их зависимостей.
7.go run
: вы можете просмотреть исходный код и запустить исходный файл команды.
Стандартная библиотека Go
1. sync: Предоставляет базовые примитивы синхронизации. Когда несколько горутин получают доступ к общим ресурсам, необходимо использовать синхронизированный механизм блокировки.
2. os: предоставляет не связанные с платформой интерфейсы доступа к функциям операционной системы. Интерфейс выполнен в стиле Unix. Предоставляемые функции включают операции с файлами, управление процессами, сигналы и учетные записи пользователей.
3, время: обработка, связанная со временем
4. fmt: реализация форматированных операций ввода и вывода.
5. io: реализует ряд не связанных с платформой интерфейсов ввода-вывода и реализаций, таких как обеспечение инкапсуляции системных функций ввода-вывода в os. Этот пакет используется, когда мы выполняем потоковое чтение и запись (например, чтение и запись файлов).
6. http: предоставление веб-сервисов
7. строка: набор функций для обработки строк, включая слияние, поиск, разделение, сравнение, проверку суффиксов, индексирование, обработку регистра и многое другое.
Рекомендация плагина VsCode
- Go: расширенная поддержка языка Go для Visual Studio Code.
Hello World
Создайтеhelloworld.go
Напишите следующее:
package main // 代码包声明语句。
import "fmt" // 系统包用来输出的
func main() {
// 打印函数调用语句。用于打印输出信息。
fmt.Println(sayHello("掘金"))
}
func sayHello(juejin string) string {
return "Hello "+juejin
}
затем выполнитьgo run helloworld.go
, Хорошо, вы уже начали. Теперь вы можете начать изучение краулера вместе. Далее я покажу вам шаг за шагом, чтобы реализовать сканирующий столбец самородков и преобразовать его в формат Markdown и сохранить его в небольшой краулер локально, с именем Этоjuejin-spider.
что такое рептилия
Определение поискового робота в энциклопедии Baidu и Википедии: Проще говоря, поисковый робот — это инструмент для сканирования содержимого целевого веб-сайта.Как правило, он автоматически выполняет сканирование в соответствии с определенным поведением, анализирует и фильтрует веб-страницу или данные; стратегия сканирования.
Проще говоря, нужно загрузить целевую веб-страницу, а затем получить нужные данные с помощью ряда операций, таких как синтаксический анализ, фильтрация и дедупликация, и сохранить их в соответствующем формате. Общий процесс выглядит следующим образом:
Коллой быстро заводится
gocolly — это фреймворк для поиска в Интернете, реализованный с помощью go. gocolly быстр и элегантен и может инициировать более 1000 запросов в секунду на одном ядре; он предоставляет набор интерфейсов в виде функций обратного вызова, которые могут реализовать любой тип сканера; опираясь на библиотеку goquery, можно выбирать веб-элементы как jquery.
Официальный сайт gocollygo-colly.org/, который содержит подробную документацию и пример кода. Установить колли:
$ go get -u github.com/gocolly/colly/...
Первая рептилия в жизни
существуетgo.mod
Управление зависимостями в:
module juejin.im/junning
go 1.14
require (
github.com/gocolly/colly/v2 latest
)
новыйmain.go
файл и напишите код:
Этот код не длинный, но я прочитал официальную документацию и пять или шесть блогов, прежде чем я его сделал, просто чтобы сделать первый краулер в моей жизни достаточно полным.
package main
import (
"fmt"
// 1、导入 colly。
"github.com/gocolly/colly"
"github.com/gocolly/colly/extensions"
)
func main() {
// 2、创建 collector
c := colly.NewCollector(colly.AllowedDomains("juejin.im")) // 要限定域名,否则就把全网都爬下来了
extensions.RandomUserAgent(c) // 使用随机的UserAgent,最好能使用代理。这样就不容易被ban
extensions.Referer(c) // 在访问的时候带上Referrer,意思就是这一次点击是从哪个页面产生的
// 3、事件监听,通过 callback 执行事件处理。
c.OnError(func(_ *colly.Response, err error) {
fmt.Println("Something went wrong:", err)
})
c.OnRequest(func(r *colly.Request) {
// fmt.Println("Visiting", r.URL)
})
// Find and visit all links
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
fmt.Println(e.Text)
e.Request.Visit(e.Attr("href"))
})
// 4、启动网页访问
c.Visit("https://juejin.cn")
}
-
:=
Способ объявления переменных и присвоения значенийВерсия Comic Go, написанная вручную) -
*clolly.HTMLElement
Синтаксис заключается в объявлении типа параметра
Обратные вызовы и порядок их вызова
Принцип gocolly заключается в отслеживании доступа к сети и предоставлении разработчикам 7 событий и обратных вызовов.
- OnRequest: вызывается перед выполнением запроса
- OnError: вызывается при сбое запроса
- OnResponseHeaders: вызывается после получения заголовков ответа, вызывается при получении заголовков ответа.
- OnResponse: вызывается, когда ответ завершен
- OnHTML: вызывается сразу после OnResponse, если полученный контент является HTML
- OnXML: вызывается сразу после OnHTML, если полученное содержимое является HTML или XML.
- OnScraped: вызывается сразу после OnXML
определение типа
перечислено здесь*colly.HTMLElement
и*colly.Request
Определение типа в процессе разработки, вы можете в любое время перейти к файлу определения типа или просмотретьGitHub.com/go колл Y/кол…Соответствующие файлы в можно (говорят, что исходники очень хорошо написаны, и у меня есть время их изучить). PS: На самом деле у TypeScript есть много общего, которое можно изучить по аналогии, поэтому я могу начать работу за одну ночь.
*colly.HTMLElement
Онлайн ссылка:GitHub.com/go колл Y/кол…
// HTMLElement is the representation of a HTML tag.
type HTMLElement struct {
// Name is the name of the tag
Name string
Text string
attributes []html.Attribute
// Request is the request object of the element's HTML document
Request *Request
// Response is the Response object of the element's HTML document
Response *Response
// DOM is the goquery parsed DOM object of the page. DOM is relative
// to the current HTMLElement
DOM *goquery.Selection
// Index stores the position of the current element within all the elements matched by an OnHTML callback
Index int
}
*colly.Request
Онлайн ссылка:GitHub.com/go колл Y/кол…
// Request is the representation of a HTTP request made by a Collector
type Request struct {
// URL is the parsed URL of the HTTP request
URL *url.URL
// Headers contains the Request's HTTP headers
Headers *http.Header
// Ctx is a context between a Request and a Response
Ctx *Context
// Depth is the number of the parents of the request
Depth int
// Method is the HTTP method of the request
Method string
// Body is the request body which is used on POST/PUT requests
Body io.Reader
// ResponseCharacterencoding is the character encoding of the response body.
// Leave it blank to allow automatic character encoding of the response body.
// It is empty by default and it can be set in OnRequest callback.
ResponseCharacterEncoding string
// ID is the Unique identifier of the request
ID uint32
collector *Collector
abort bool
baseURL *url.URL
// ProxyURL is the proxy address that handles the request
ProxyURL string
}
Сканировать колонку Nuggets
Принцип действия поискового робота заключается в имитации доступа к веб-странице, получении информации о документе, преобразовании информации в необходимые данные с помощью различных средств и сохранении данных.
Поскольку автор спешит начать работу с языком Go за одну ночь и не может реализовать краулер для сканирования данных, я реализовал следующее:
访问掘金专栏详情页
⏬
获取指定的内容和标题部分
⏬
将标题作为文件名
⏬
把内容转为Markdown格式存入文件
⏬
保存文件到本地
Анализировать структуру страницы
Структура заголовка столбца
<h1 data-v-23a9d5ed="" class="article-title">(.*?)<\/h1>
Структура корпуса колонны
<div class="markdown-body">(.*?)<\/div>
Получить заголовок и содержимое столбца
func main() {
c := colly.NewCollector(
colly.Async(true),
)
c.OnRequest(func(r *colly.Request) {
fmt.Println("Visiting", r.URL)
})
c.OnError(func(_ *colly.Response, err error) {
log.Println("Something went wrong:", err)
})
c.OnHTML(".article-title", func(e *colly.HTMLElement) {
// Code Here
})
c.OnHTML(".markdown-body", func(e *colly.HTMLElement) {
// Code Here
})
c.Visit("https://juejin.im/post/" + *post)
c.Wait()
}
-
colly.NewCollector
добавил одинcolly.Async(true)
, что означает, что выборка является асинхронной, что может значительно повысить скорость выборки. - использовать
OnHTML
События захватываются отдельно с помощьюarticle-title
и.markdown-body
Элемент, который является местом реализации логики функции, которую мы хотим реализовать ниже. -
OnHTML
Первый параметр соответствует правилам селектора CSS, вы можете использовать любой селектор, чтобы что-то делать.
Конвертировать HTML в Markdown
Здесь мы используемhtml-to-markdownФункции, предоставляемые этой библиотекой, мы просто инкапсулируем в ней:
// 将Html转为Markdown
func convertHTMLToMarkdown(selection *goquery.Selection) string {
converter := md.NewConverter("", true, nil)
markdown := converter.Convert(selection)
return markdown
}
сохранить файл на локальном
...
// 写入文件
func writeFile(fileName string,content string) {
filePath := fileName + ".md"
var file *os.File
if checkFileIsExist(filePath) {
// 如果文件存在,则删除
err := os.Remove(filePath)
if err != nil {
log.Fatal(err)
}
}
// 创建文件并写入内容
file, _ = os.Create(filePath)
n, _ := io.WriteString(file, "## "+fileName+"\n\n"+content)
// 关闭文件
file.Close()
if n == 0 {
return
}
}
// 检查文件是否存在
func checkFileIsExist(fileName string) bool {
_, err := os.Stat(fileName)
if err != nil {
return false
}
return true
}
...
-
os.Stat
: используется для получения информации о файле или файле, на основе которой он инкапсулируетcheckFileIsExist
Проверьте, существует ли файл -
os.Create
+io.WriteString
Реализовано создание файлов и запись в файлы - Чтобы определить, существует ли файл, используйте
os.Remove(filePath)
Удалите файл, чтобы перезаписать файл (лень смотреть метод перезаписывания файла)
Получить аргументы командной строки
Этот метод написания подобен, когда я использую NodeJS для написания инструментов CLI.Если вам интересно, вы можетепосмотри,Не обязательно в следующий раз, только в этот раз.
func main() {
var post = flag.String("post", "6859538537830858759", "文章编号")
var rootDir = flag.String("root", root, "文件保存的根目录")
flag.Parse()
}
получить переменные окружения
Использование не поддерживается на языке GO~
Число представляет собой домашний каталог.После долгих метаний я нашел это решение.Это не то же самое, что и Deno.Этот языковой дизайн заимствован (копирован) друг у друга.
os.Getenv("HOME")
получить фотографии
При тестировании скрипта я обнаружил что статьи с картинками пропали.Как это может работать?Статьи без картинок не имеют души. Результат анализа — изображение Наггетса загружается лениво, а метка выглядит так:
<img class="lazyload inited loaded" data-src="https://i.loli.net/2020/08/13/cVomW7L9YOTw2uA.png" data-width="800" data-height="600" src="https://i.loli.net/2020/08/13/cVomW7L9YOTw2uA.png">
Я думаю, этоdata-
проблема с атрибутами, поэтому я добавил в скрипт следующий код, чтобыdata-
Удалить:
...
reg := regexp.MustCompile(`data-`)
html, _ := e.DOM.Html()
markdown := convertHTMLToMarkdown(reg.ReplaceAllString(html, ""))
...
youngjuning/homebrew-juejin-spider@0.1.0Он был выпущен, и он может отлично захватить колонку Nuggets.
готовый продукт
Код слишком длинный, исходный код здесь 》》》На GitHub.com/ есть этот гигантский нин..."", я все это прочитал здесь, поставьте мне звезду.
Упакуйте и опубликуйте скрипт с помощью Homebrew
Хакеров надо преследовать, из игрушки сделать невозможно. А сам Go работает без каких-либо зависимостей и окружений, я не могу просить людей, использующих инструменты, установить go-окружение. Моей первой мыслью было отправить мой скрипт в Homebrew, слава богу,Публикация скриптов с помощью HomeBrewЭтот процесс подробно описан.
1. Упакуйте его в исполняемый файл
$ go build juejin.go
В текущем каталоге будет сгенерирован исполняемый файл с именем juejin,./juejin
является исполняемым, вы также можете использоватьgo build -o=/usr/local/bin juejin.go
илиgo build -o=$GOPATH/bin/ juejin.go
в зарегистрированный системный путь.
2. Упаковать исполняемый файл в формат tar.gz
$ tar zcvf juejin_0.0.1.tar.gz juejin
Загрузите в git рецепт для символической ссылки на этот файл скрипта.
3. Используйтеbrew create <git-url> --tab user/repo
Создать рецепт
$ brew create \
https://github.com/youngjuning/homebrew-juejin-spider/raw/master/juejin_0.0.1.tar.gz \
--tap youngjuning/homebrew-juejin-spider
Нам нужно внести некоторые коррективы в метод установки:
def install
bin.install "juejin"
end
После выполнения этих операций сохраните и отправьте в git.
4. Скрипт установки
$ brew install youngjuning/juejin-spider/juejin
воплощать в жизньjuejin -h
Проверить на успех:
$ juejin -h
Usage of juejin:
-post string
文章编号 (default "6859538537830858759")
-root string
文件保存的根目录 (default "/Users/yangjunning/juejin")
Устанавливайте собственные скрипты на чужие устройства
// 在执行这个命令的时候,brew会自动去更新自己的formula仓库,会耗时几分钟。。。
$ brew tap youngjuning/juejin-spider https://github.com/youngjuning/homebrew-juejin-spider.git
// 下载、安装脚本
$ brew install youngjuning/juejin-spider/juejin
супер сайян город
Спасибо, что терпеливо читаете эту статью. Нравится — значит учится, коллекции — это мастерство, а лайки и коллекции — это настоящая любовь! ! ! С нетерпением жду обсуждения со мной в разделе комментариев! ! !