Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Colly: обзор фреймворка для веб-скрейпинга на Go
Search
Iskander (Alex) Sharipov
September 22, 2019
Programming
0
250
Colly: обзор фреймворка для веб-скрейпинга на Go
Iskander (Alex) Sharipov
September 22, 2019
Tweet
Share
More Decks by Iskander (Alex) Sharipov
See All by Iskander (Alex) Sharipov
quasigo
quasilyte
0
53
Go gamedev: XM music
quasilyte
0
110
Zero alloc pathfinding
quasilyte
0
490
Mycelium
quasilyte
0
62
Roboden game pitch
quasilyte
0
210
Ebitengine Ecosystem Overview
quasilyte
1
870
Go gamedev patterns
quasilyte
0
470
profile-guided code analysis
quasilyte
0
360
Go inlining
quasilyte
0
120
Other Decks in Programming
See All in Programming
decksh - a little language for decks
ajstarks
4
21k
State of CSS 2025
benjaminkott
1
110
AIエージェント開発、DevOps and LLMOps
ymd65536
1
320
Claude Code と OpenAI o3 で メタデータ情報を作る
laket
0
130
マイコンでもRustのtestがしたい その2/KernelVM Tokyo 18
tnishinaga
2
2.3k
なぜ今、Terraformの本を書いたのか? - 著者陣に聞く!『Terraformではじめる実践IaC』登壇資料
fufuhu
4
640
[FEConf 2025] 모노레포 절망편, 14개 레포로 부활하기까지 걸린 1년
mmmaxkim
0
860
Flutterと Vibe Coding で個人開発!
hyshu
1
260
Terraform やるなら公式スタイルガイドを読もう 〜重要項目 10選〜
hiyanger
13
3.2k
GitHub Copilotの全体像と活用のヒント AI駆動開発の最初の一歩
74th
8
3.1k
STUNMESH-go: Wireguard NAT穿隧工具的源起與介紹
tjjh89017
0
380
kiroでゲームを作ってみた
iriikeita
0
180
Featured
See All Featured
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
183
54k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Code Reviewing Like a Champion
maltzj
525
40k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
YesSQL, Process and Tooling at Scale
rocio
173
14k
How to train your dragon (web standard)
notwaldorf
96
6.2k
Why Our Code Smells
bkeepers
PRO
338
57k
Making Projects Easy
brettharned
117
6.3k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Transcript
Colly: обзор фреймворка для веб-скрейпинга на Go Joanna Shevchuk
О себе • Go + Python + Linux; • Менторю
Django Girls и курс PyLadies 1/22
Веб-скрейпинг извлечение данных из веб-страниц для последующей структуризации. 2/22
API Программный интерфейс приложения описание способов, помогающих одной программе взаимодействовать
с другой. Есть API - используем API. Нет API - используем скрейпер. 3/22
robots.txt наш_сайт/robots.txt User-agent: * Disallow: / (скрейпить нельзя помиловать **)
4/22
Colly: Fast and Elegant Scraping Framework for Gophers 5/22
Преимущества • Толковый API и подробная документация; • Много плюшек;
• На Go = привычнее; • Конкурентность. 6/22
О плюшках: • Скрейпит синхронно/асинхронно/параллельно; • Автоматически кодирует не-Юникодные символы;
• Сам вычищает cookies; • Обрабатывает robots.txt; • Можно прикрутить БД: SQLite или MongoDB; 7/22
Недостатки • Нет встроенного headless-браузера; Headless browser браузер без графического
интерфейса (работает через командную строку). 8/22
func main() { c := colly.NewCollector() c.OnHTML("a[href]", func(e *colly.HTMLElement) {
e.Request.Visit(e.Attr("href")) }) c.OnRequest(func(r *colly.Request) { fmt.Println("Visiting", r.URL) }) c.Visit("http://go-colly.org/") } 9/22
type Collector struct { UserAgent string MaxDepth int AllowedDomains []string
DisallowedDomains []string DisallowedURLFilters []*regexp.Regexp URLFilters []*regexp.Regexp AllowURLRevisit bool MaxBodySize int CacheDir string IgnoreRobotsTxt bool Async bool ParseHTTPErrorResponse bool ID uint32 DetectCharset bool RedirectHandler func(req *http.Request, via []*http.Request) error CheckHead bool } 10/22
User Agent как концепция приложение, через определенный сетевой протокол обеспечивающее
доступ к веб-контенту (например, браузер или скрейпер). как элемент строка, содержащая сведения о браузере или скрейпере: название, версия, платформа (ОС), движок. 11/22
Скрейпим статический сайт package main import ( "encoding/csv" "log" "os"
"github.com/gocolly/colly" ) func main() { fName := "xkcd_store_items.csv" file, err := os.Create(fName) if err != nil { log.Fatalf("Cannot create file %q: %s\n", fName, err) return } 12/22
... defer file.Close() writer := csv.NewWriter(file) defer writer.Flush() writer.Write([]string{"Name", "Price",
"URL", "Image URL"}) c := colly.NewCollector( colly.AllowedDomains("store.xkcd.com"), ) ... 13/22
... c.OnHTML(‘.next a[href]‘, func(e *colly.HTMLElement) { e.Request.Visit(e.Attr("href")) }) c.Visit("https://store.xkcd.com/collections/everything") log.Printf("Scraping
finished, check file %q for results\n", fName) log.Println(c) } 14/22
Скрейпим динамический сайт (не через родной API) Instagram Под капотом
есть goquery. • Исходный код страницы • Ищем переменную window._sharedData 15/22
c := colly.NewCollector() c.OnHTML("body > script:first-of-type", func(e *colly.HTMLElement ) {
jsonData := e.Text[strings.Index(e.Text, "{") : len(e.Text) -1] 16/22
data := struct { EntryData struct { ProfilePage []struct {
User struct { Id string ‘json:"id"‘ Media struct { Nodes []struct { ImageURL string ‘json:"display_src "‘ ThumbnailURL string ‘json:" thumbnail_src"‘ IsVideo bool ‘json:"is_video"‘ Date int ‘json:"date"‘ Dimensions struct { Width int ‘json:"width"‘ Height int ‘json:"height"‘ } } ... 17/22
... PageInfo pageInfo ‘json:"page_info"‘ } ‘json:"media"‘ } ‘json:"user"‘ } ‘json:"ProfilePage"‘
} ‘json:"entry_data"‘ }{} err := json.Unmarshal([]byte(jsonData), &data) if err != nil { log.Fatal(err) } 18/22
page := data.EntryData.ProfilePage[0] actualUserId = page.User.Id for _, obj :=
range page.User.Media.Nodes { if obj.IsVideo { continue } c.Visit(obj.ImageURL) } } 19/22
const nextPageURLTemplate string = ‘https://www.instagram.com/ graphql/query/?query_id=17888483320059182&variables={"id":"%s ","first":12,"after":"%s"}‘ //... c.OnResponse(func(r *colly.Response)
{ if strings.Index(r.Headers.Get("Content-Type"), "image") > -1 { r.Save(outputDir + r.FileName()) return } } 20/22
http://go-colly.org/ https://github.com/gocolly/colly https://godoc.org/github.com/gocolly/colly https://godoc.org/github.com/gocolly/colly/extensions 21/22
Мои контакты djeanne joannashevchuk ƻ djeanne djeanne.github.io
[email protected]
[email protected]
22/22