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: a review of a web-scraping framework in Go
Search
Joanna Shevchuk
September 22, 2019
Programming
0
370
Colly: a review of a web-scraping framework in Go
A brief review of the web-scraping framework Colly, the most popular one among Gophers.
Joanna Shevchuk
September 22, 2019
Tweet
Share
More Decks by Joanna Shevchuk
See All by Joanna Shevchuk
pip uninstall depression
djeanne
0
86
Go for Python speakers
djeanne
0
88
Other Decks in Programming
See All in Programming
GoのGenericsによるslice操作との付き合い方
syumai
3
690
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
260
DroidKnights 2025 - 다양한 스크롤 뷰에서의 영상 재생
gaeun5744
3
320
型付きアクターモデルがもたらす分散シミュレーションの未来
piyo7
0
810
なぜ「共通化」を考え、失敗を繰り返すのか
rinchoku
1
530
プロダクト志向なエンジニアがもう一歩先の価値を目指すために意識したこと
nealle
0
110
GraphRAGの仕組みまるわかり
tosuri13
8
490
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
490
ReadMoreTextView
fornewid
1
480
都市をデータで見るってこういうこと PLATEAU属性情報入門
nokonoko1203
1
570
#kanrk08 / 公開版 PicoRubyとマイコンでの自作トレーニング計測装置を用いたワークアウトの理想と現実
bash0c7
1
500
関数型まつりレポート for JuliaTokai #22
antimon2
0
160
Featured
See All Featured
Building an army of robots
kneath
306
45k
Done Done
chrislema
184
16k
The World Runs on Bad Software
bkeepers
PRO
69
11k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
4 Signs Your Business is Dying
shpigford
184
22k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.2k
Testing 201, or: Great Expectations
jmmastey
42
7.5k
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.6k
A Tale of Four Properties
chriscoyier
160
23k
How to Ace a Technical Interview
jacobian
277
23k
How GitHub (no longer) Works
holman
314
140k
The Language of Interfaces
destraynor
158
25k
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