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
290
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Colly: обзор фреймворка для веб-скрейпинга на Go
Iskander (Alex) Sharipov
September 22, 2019
More Decks by Iskander (Alex) Sharipov
See All by Iskander (Alex) Sharipov
quasigo
quasilyte
0
100
Go gamedev: XM music
quasilyte
0
150
Zero alloc pathfinding
quasilyte
0
760
Mycelium
quasilyte
0
100
Roboden game pitch
quasilyte
0
290
Ebitengine Ecosystem Overview
quasilyte
1
1k
Go gamedev patterns
quasilyte
0
540
profile-guided code analysis
quasilyte
0
390
Go inlining
quasilyte
0
170
Other Decks in Programming
See All in Programming
The ROI of Quarkus for Spring Boot Applications
hollycummins
0
140
Creating Composable Callables in Contemporary C++
rollbear
0
170
OSもどきOS
arkw
0
590
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
300
AI時代のUIはどこへ行く?その2!
yusukebe
22
7.5k
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
8.3k
ADKを使って簡単にAIエージェントを作ってみよう
k1mu21
0
280
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
220
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
geekplus_tech
0
410
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
200
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
560
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
270
Featured
See All Featured
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Six Lessons from altMBA
skipperchong
29
4.3k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
For a Future-Friendly Web
brad_frost
183
10k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
220
It's Worth the Effort
3n
188
29k
The Curious Case for Waylosing
cassininazir
1
400
First, design no harm
axbom
PRO
2
1.2k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
370
BBQ
matthewcrist
89
10k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
200
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
400
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