Rumah > Artikel > pembangunan bahagian belakang > Cara menulis crawler dalam golang
Dengan populariti Internet, kami perlu mendapatkan sejumlah besar maklumat, dan sebahagian besar maklumat ini memerlukan kami merangkaknya dari tapak web. Terdapat banyak kaedah merangkak, antaranya perangkak yang ditulis dalam golang boleh membantu kami mendapatkan maklumat ini dengan lebih cekap.
Golang ialah bahasa pengaturcaraan yang intuitif, ringkas dan cekap, sesuai untuk senario aplikasi berkonkurensi tinggi dan berprestasi tinggi, dan perangkak ialah tugas berkonkurensi tinggi, berprestasi tinggi, jadi ia sangat sesuai untuk menulis perangkak dalam golang of. Dalam artikel ini, kami akan memperkenalkan proses asas, perpustakaan yang biasa digunakan dan teknologi teras untuk menulis perangkak di Golang untuk membantu pemula menguasai kaedah asas perangkak Golang dengan cepat.
1. Langkah asas untuk menulis crawler dalam golang
Sebelum memperkenalkan langkah asas untuk menulis crawler dalam golang, kita perlu memahami struktur asas HTML.
Dalam perpustakaan standard golang, fungsi berkaitan untuk permintaan HTTP telah disediakan Kami hanya perlu menetapkan URL, pengepala permintaan, kuki dan parameter permintaan . Setelah anda mempunyai maklumat asas, anda boleh membina permintaan HTTP yang anda perlukan. Kod utama adalah seperti berikut:
package main import ( "fmt" "io/ioutil" "net/http" ) func main() { resp, err := http.Get("http://www.baidu.com") if err != nil { fmt.Println(err) return } defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(body)) }
Kod ini menggunakan fungsi http.Get untuk memulakan permintaan HTTP dan membaca badan respons daripada respons. Perkara utama ialah pernyataan penangguhan, yang akan dilaksanakan pada penghujung fungsi untuk menutup badan tindak balas dan mengelakkan kebocoran sumber.
Data respons yang diperolehi oleh permintaan HTTP ialah dokumen HTML, yang perlu kami huraikan untuk mendapatkan data yang diperlukan. Dalam golang, kita boleh menggunakan pustaka GoQuery untuk menghuraikan dokumen HTML. Pustaka ini adalah berdasarkan sintaks jQuery dan mudah digunakan.
Fungsi penghuraian utama yang disediakan oleh GoQuery ialah: Cari, Penapis, Setiap, Attr, dsb. Fungsi Cari digunakan untuk mencari sub-elemen yang memenuhi kriteria, dan fungsi Penapis digunakan untuk menapis elemen yang memenuhi kriteria. Fungsi Setiap digunakan untuk melintasi semua elemen yang memenuhi syarat, manakala fungsi Attr digunakan untuk mendapatkan atribut elemen. Mengambil analisis laman utama Baidu sebagai contoh, kodnya adalah seperti berikut:
package main import ( "fmt" "github.com/PuerkitoBio/goquery" "log" ) func main() { resp, err := http.Get("http://www.baidu.com") if err != nil { log.Fatal(err) } body := resp.Body defer body.Close() doc, err := goquery.NewDocumentFromReader(body) if err != nil { log.Fatal(err) } doc.Find("title").Each(func(i int, s *goquery.Selection) { fmt.Println(s.Text()) }) }
Dalam kod di atas, fungsi goquery.NewDocumentFromReader digunakan untuk membina objek dokumen, dan kemudian elemen tajuk ditemui melalui Cari kaedah, dan semua elemen yang layak dilalui melalui kaedah Setiap, dan teks.
Langkah terakhir ialah menyimpan data yang diperolehi. Untuk penyimpanan data, kami mempunyai banyak cara untuk dipilih, seperti pangkalan data, fail, cache, dll.
Sebagai contoh, kami ingin menyimpan data yang dirangkak ke dalam fail CSV Langkah-langkahnya adalah seperti berikut:
package main import ( "encoding/csv" "log" "os" ) func main() { file, err := os.Create("data.csv") if err != nil { log.Fatal(err) } defer file.Close() writer := csv.NewWriter(file) defer writer.Flush() writer.Write([]string{"name", "address", "tel"}) writer.Write([]string{"John Smith", "123 Main St, Los Angeles, CA 90012", "123-456-7890"}) writer.Write([]string{"Jane Smith", "456 Oak Ave, San Francisco, CA 94107", "123-456-7891"}) }
Dalam kod di atas, fail bernama data.csv dicipta menggunakan os. .Buat fungsi. Kemudian buat penulis CSV melalui fungsi csv.NewWriter. Akhir sekali, kami menulis data untuk disimpan ke dalam fail CSV melalui kaedah writer.Write.
2. Pustaka biasa untuk menulis perangkak dalam golang
Menulis perangkak dalam golang tidak memerlukan anda menulis sendiri banyak kod asas adalah seperti berikut:
Gocolly ialah rangka kerja perangkak ringan berdasarkan golang, yang menyediakan banyak kaedah mudah untuk membantu merangkak data. Ia secara automatik boleh mengendalikan isu seperti ubah hala, kuki, proksi, had laju, dsb., membolehkan kami menumpukan lebih pada penentuan peraturan pengekstrakan data. Kod berikut menunjukkan cara menggunakan Gocolly untuk mendapatkan tajuk Baidu:
package main import ( "fmt" "github.com/gocolly/colly" ) func main() { c := colly.NewCollector() c.OnHTML("head", func(e *colly.HTMLElement) { title := e.ChildText("title") fmt.Println(title) }) c.Visit("http://www.baidu.com") }
beautifulsoup4go ialah parser HTML berasaskan golang, sama seperti perpustakaan Python yang terkenal BeautifulSoup4 , boleh menghuraikan halaman HTML yang berbeza daripada Internet. Kod berikut menunjukkan cara menggunakan beautifulsoup4go untuk mendapatkan tajuk Baidu:
package main import ( "fmt" "github.com/sundy-li/go_commons/crawler" ) func main() { html := crawler.FetchHTML("http://www.baidu.com", "GET", nil, "") bs := crawler.NewSoup(html) title := bs.Find("title").Text() fmt.Println(title) }
Pustaka goquery telah diperkenalkan lebih awal, ia adalah penghurai HTML berdasarkan pemilih CSS , menyokong operasi rantaian dan merupakan perpustakaan yang sangat praktikal. Kod berikut menunjukkan cara menggunakan goquery untuk mendapatkan tajuk Baidu:
package main import ( "fmt" "github.com/PuerkitoBio/goquery" "log" ) func main() { resp, err := http.Get("http://www.baidu.com") if err != nil { log.Fatal(err) } body := resp.Body defer body.Close() doc, err := goquery.NewDocumentFromReader(body) if err != nil { log.Fatal(err) } title := doc.Find("title").Text() fmt.Println(title) }
Tiga perpustakaan di atas mempunyai ciri tersendiri. Memilih perpustakaan yang sesuai dengan anda boleh melengkapkan rangkak dengan lebih cekap.
3. Teknologi teras Golang untuk menulis crawler
Dalam proses melaksanakan crawler, ciri yang sangat penting ialah concurrency, iaitu, akses serentak Berbilang laman web atau berbilang URL. Dalam golang, kami boleh melaksanakan tugas secara serentak melalui coroutine, contohnya:
package main import ( "fmt" "github.com/gocolly/colly" ) func main() { urls := []string{ "http://www.baidu.com", "http://www.sogou.com", "http://www.google.com", } ch := make(chan string, len(urls)) for _, url := range urls { go func(url string) { c := colly.NewCollector() c.OnHTML("head", func(e *colly.HTMLElement) { title := e.ChildText("title") ch <- title }) c.Visit(url) }(url) } for range urls { title := <-ch fmt.Println(title) } }
Dalam kod di atas, kami menggunakan coroutine untuk mengakses berbilang URL serentak dan mengekstrak tajuk daripada teg kepala setiap maklumat dan cetakan.
Seperti yang kita sedia maklum, untuk mengehadkan akses perangkak, banyak tapak web akan menggunakan mekanisme anti-crawler, seperti mengehadkan kekerapan permintaan , menambah kod pengesahan dan mengenal pasti alat crawler biasa. Untuk mekanisme anti-crawler ini, kami perlu menggunakan beberapa cara teknikal untuk mengelak daripada diharamkan daripada tapak web. Berikut adalah dua cara teknikal:
(1) Kawalan kekerapan capaian
Untuk mengelak daripada disekat oleh tapak web dalam kekerapan akses, kami boleh menetapkan selang akses, menggunakan IP proksi, menggunakan kaedah yang diedarkan , dsb. Bermaksud untuk mengelak daripada dikenal pasti oleh mekanisme anti-reptilia.
Sebagai contoh, dalam rangka kerja Gocolly, kita boleh menggunakan kaedah seperti WaitTime, RandomDelay dan Limit untuk menetapkan kekerapan merangkak dan had permintaan:
package main import ( "fmt" "github.com/gocolly/colly" "time" ) func main() { c := colly.NewCollector() c.Limit(&colly.LimitRule{ DomainGlob: "*", Parallelism: 2, RandomDelay: 5 * time.Second, }) c.OnHTML("head", func(e *colly.HTMLElement) { title := e.ChildText("title") fmt.Println(title) }) c.Visit("http://www.baidu.com") }
Dalam kod di atas, bilangan akses serentak ditetapkan kepada 2 dan selang permintaan Ia adalah 5 saat, yang boleh mengelak daripada disekat oleh tapak web dengan berkesan. Sudah tentu, dalam penggunaan sebenar, kami juga perlu menetapkan selang akses yang munasabah mengikut tapak web yang berbeza.
(2) Merangkak teragih
Merangkak yang diedarkan boleh mengelak daripada dihadkan oleh tapak web dengan berkesan dan meningkatkan kecekapan merangkak. Idea asas adalah untuk menetapkan tugas yang berbeza kepada nod atau mesin yang berbeza, memprosesnya secara bebas, dan meringkaskan hasilnya bersama-sama. Rangkaan teragih memerlukan penjadualan, komunikasi dan teknologi lain, yang agak rumit. Dalam perangkak sebenar, kami boleh menggunakan perpustakaan atau perkhidmatan awan pihak ketiga untuk melaksanakan rangkak teragih.
Kesimpulan
Artikel ini memperkenalkan cara menggunakan golang untuk menulis perangkak, termasuk langkah asas, perpustakaan biasa dan teknologi teras. Golang ialah bahasa berprestasi tinggi, ringkas dan jelas yang dapat memenuhi keperluan perangkak. Walau bagaimanapun, dalam amalan merangkak, kita masih perlu memahami lebih banyak teknologi dan sentiasa mempelajari teknologi anti-merangkak yang lebih baharu untuk berjaya menyelesaikan tugasan merangkak.
Atas ialah kandungan terperinci Cara menulis crawler dalam golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!