Pesaing Scrapper

Barbara Streisand
Barbara Streisandasal
2024-11-06 15:21:031043semak imbas

Scrapper Concorrente

Objektif program

Akses halaman web pada masa yang sama untuk mengekstrak tajuk setiap halaman dan memaparkan tajuk ini dalam terminal. Ini dilakukan menggunakan concurrency dalam Go, yang membolehkan anda mengakses berbilang halaman secara serentak, menjimatkan masa.

Penjelasan Kod

Pakej yang digunakan

import (
    "fmt"
    "net/http"
    "sync"
    "github.com/PuerkitoBio/goquery"
)

fungsi fetchTitle

Peranan ini bertanggungjawab untuk:

  • Akses halaman web (url)
  • Ekstrak tajuk halaman
  • Evniate hasil ke saluran
func fetchTitle(url string, wg *sync.WaitGroup, results chan<- string) {
    defer wg.Done() // Marca a goroutine como concluída no WaitGroup

Parameter fungsi:

  • rentetan url: Mewakili alamat halaman web (url) yang akan kami akses untuk mendapatkan tajuk
  • wg *sync.WaitGroup: Penunjuk ke WaitGroup, yang kami gunakan untuk menyegerakkan penyiapan semua tugasan (goroutine) yang berjalan pada masa yang sama. * menunjukkan bahawa kami menghantar "alamat" kepada WaitGroup` dan bukan salinannya.
  • hasil chan<- rentetan: Ini ialah saluran sehala yang membolehkan anda menghantar rentetan ke bahagian lain program. Ia digunakan untuk menghantar hasil (tajuk atau mesej ralat) ke fungsi utama

Barisan tangguh wg.Done() memberitahu program untuk menandakan tugas ini (goroutine) sebagai selesai apabila fungsi fetchTitle selesai. Ini penting supaya main tahu bila semua tugasan telah selesai.

Permintaan HTTP


req, err := http.Get(url)
if err != nil {
hasil <- fmt.Sprintf("Ralat mengakses %s: %v", url, err)
kembali
}
tangguh req.Body.Close()

  • http.Get(url): Baris ini membuat permintaan HTTP GET ke URL. Ini bermakna kami sedang mengakses halaman dan meminta pelayan untuk kandungannya.
  • err != nil: Di sini kami menyemak sama ada terdapat sebarang ralat semasa mengakses halaman (contohnya, jika halaman itu tidak wujud atau pelayan tidak bertindak balas). Jika terdapat ralat, kami menghantar mesej ke saluran hasil dan menamatkan fungsi dengan pulangan.
  • tunda req.Body.Close(): Ini memastikan bahawa selepas kami selesai menggunakan kandungan halaman, kami mengosongkan memori yang diperuntukkan untuk menyimpannya.

Semakan Status


if req.StatusCode != 200 {
hasil <- fmt.Sprintf("Ralat mengakses %s: status %d %s", url, req.StatusCode, req.Status)
kembali
}

  • req.StatusCode != 200: Kami menyemak sama ada pelayan membalas dengan kod 200 OK (menunjukkan kejayaan). Jika bukan 200, ini bermakna halaman tidak dimuatkan dengan betul. Kami kemudian menghantar mesej ralat ke saluran hasil dan menamatkan fungsi.

Pemuatan dan Carian Tajuk


doc, err := goquery.NewDocumentFromReader(req.Body)
if err != nil {
hasil <- fmt.Sprintf("Ralat memuatkan dokumen daripada %s: %v", url, err)
kembali
}
tajuk := doc.Find("title").Teks()
hasil <- fmt.Sprintf("Tajuk %s: %s", url, tajuk)
}

  • goquery.NewDocumentFromReader(req.Body): Kami memuatkan kandungan HTML halaman (disediakan oleh req.Body) ke dalam goquery, yang membolehkan anda menavigasi dan mencari bahagian tertentu HTML.
  • doc.Find("title").Teks(): Kami mencari tag dalam HTML halaman dan dapatkan teks di dalamnya (iaitu tajuk). </pre> <li> <strong>hasil <- fmt.Sprintf("Título de %s: %s", url, title)</strong>: Kami menghantar tajuk yang diekstrak ke saluran hasil, di mana ia akan dibaca kemudian.</li> <h2> fungsi utama </h2> <p>Fungsi utama ialah fungsi utama yang mengkonfigurasi dan mengawal atur cara.</p> <p><br> func main() {<br> url := []rentetan{<br> "http://olos.novagne.com.br/Olos/login.aspx?logout=true",<br> "http://sistema.novagne.com.br/novagne/",<br> }<br> </p> <ul> <li> <strong>url := []rentetan{...}</strong>: Kami mentakrifkan senarai URL yang ingin kami proses. Setiap URL akan dihantar ke goroutine yang akan mengekstrak tajuk halaman.</li> </ul> <h2> WaitGroup dan Konfigurasi Saluran </h2> <p><br> var wg sync.WaitGroup<br> hasil := make(chan string, len(urls)) // Saluran untuk menyimpan hasil<br> </p> <ul> <li> <strong>var wg sync.WaitGroup</strong>: Kami mencipta tika baharu WaitGroup, yang akan mengawal bilangan goroutin dan memastikan semuanya selesai sebelum program tamat.</li> <li> <strong>hasil := make(chan string, len(urls))</strong>: Kami mencipta saluran hasil dengan kapasiti yang sama dengan bilangan URL Saluran ini akan menyimpan mesej dengan tajuk atau ralat.</li> </ul> <h2> Rumah Goroutines </h2> <p><br> untuk _, url := url julat {<br> wg.Tambah(1)<br> pergi fetchTitle(url, &wg, hasil)<br> }<br> </p> <ul> <li> <strong>untuk _, url := url julat</strong>: Di sini kita mengulangi setiap URL dalam senarai.</li> <li> <strong>wg.Add(1)</strong>: Untuk setiap URL, kami menambah pembilang WaitGroup untuk menunjukkan bahawa tugas baharu (goroutine) akan dimulakan.</li> <li> <strong>go fetchTitle(url, &wg, results)</strong>: Kami memanggil fetchTitle sebagai <strong>goroutine</strong> untuk setiap URL, iaitu, kami menjadikannya berjalan selari dengan yang lain.</li> </ul> <h2> Menunggu dan Memaparkan Keputusan </h2> <p><br> wg.Tunggu()<br> tutup(hasil)<br> </p> <hr> <p>REPO: https://github.com/ionnss/Scrapper-GoRoutine</p> <hr> <p>ion,</p> <p>hari bumi yang lain</p> <p>Atas ialah kandungan terperinci Pesaing Scrapper. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!</p></div><div class="nphpQianMsg"><a href="javascript:void(0);">html</a> <a href="javascript:void(0);">String</a> <a href="javascript:void(0);">if</a> <a href="javascript:void(0);">for</a> <a href="javascript:void(0);">var</a> <a href="javascript:void(0);">len</a> <a href="javascript:void(0);">nil</a> <a href="javascript:void(0);">github</a> <a href="javascript:void(0);">http</a> <a href="javascript:void(0);">https</a><div class="clear"></div></div><div class="nphpQianSheng"><span>Kenyataan:</span><div>Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn</div></div></div><div class="nphpSytBox"><span>Artikel sebelumnya:<a class="dBlack" title="Dari C# to Go: Mencapai Keserasian Pengekodan AES dan Base64" href="https://m.php.cn/ms/faq/1796672826.html">Dari C# to Go: Mencapai Keserasian Pengekodan AES dan Base64</a></span><span>Artikel seterusnya:<a class="dBlack" title="Dari C# to Go: Mencapai Keserasian Pengekodan AES dan Base64" href="https://m.php.cn/ms/faq/1796672838.html">Dari C# to Go: Mencapai Keserasian Pengekodan AES dan Base64</a></span></div><div class="nphpSytBox2"><div class="nphpZbktTitle"><h2>Artikel berkaitan</h2><em><a href="https://m.php.cn/ms/article.html" class="bBlack"><i>Lihat lagi</i><b></b></a></em><div class="clear"></div></div><ins class="adsbygoogle" style="display:block" data-ad-format="fluid" data-ad-layout-key="-6t+ed+2i-1n-4w" data-ad-client="ca-pub-5902227090019525" data-ad-slot="8966999616"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script><ul class="nphpXgwzList"><li><b></b><a href="https://m.php.cn/ms/faq/419133.html" title="什么是Go语言?Go语言的优缺点介绍" class="aBlack">什么是Go语言?Go语言的优缺点介绍</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/ms/faq/419289.html" title="gin是什么意思?" class="aBlack">gin是什么意思?</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/ms/faq/421167.html" title="go 为什么比php性能高" class="aBlack">go 为什么比php性能高</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/ms/faq/421591.html" title="go语言适合做什么?" class="aBlack">go语言适合做什么?</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/ms/faq/422570.html" title="go语言基础" class="aBlack">go语言基础</a><div class="clear"></div></li></ul></div></div><ins class="adsbygoogle" style="display:block" data-ad-format="autorelaxed" data-ad-client="ca-pub-5902227090019525" data-ad-slot="5027754603"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script><footer><div class="footer"><div class="footertop"><img src="/static/imghwm/logo.png" alt=""><p>Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!</p></div><div class="footermid"><a href="https://m.php.cn/ms/about/us.html">Tentang kita</a><a href="https://m.php.cn/ms/about/disclaimer.html">Penafian</a><a href="https://m.php.cn/ms/update/article_0_1.html">Sitemap</a></div><div class="footerbottom"><p> © php.cn All rights reserved </p></div></div></footer><script>isLogin = 0;</script><script type="text/javascript" src="/static/layui/layui.js"></script><script type="text/javascript" src="/static/js/global.js?4.9.47"></script></div><script src="https://vdse.bdstatic.com//search-video.v1.min.js"></script><link rel='stylesheet' id='_main-css' href='/static/css/viewer.min.css' type='text/css' media='all'/><script type='text/javascript' src='/static/js/viewer.min.js?1'></script><script type='text/javascript' src='/static/js/jquery-viewer.min.js'></script><script>jQuery.fn.wait = function (func, times, interval) { var _times = times || -1, //100次 _interval = interval || 20, //20毫秒每次 _self = this, _selector = this.selector, //选择器 _iIntervalID; //定时器id if( this.length ){ //如果已经获取到了,就直接执行函数 func && func.call(this); } else { _iIntervalID = setInterval(function() { if(!_times) { //是0就退出 clearInterval(_iIntervalID); } _times <= 0 || _times--; //如果是正数就 -- _self = $(_selector); //再次选择 if( _self.length ) { //判断是否取到 func && func.call(_self); clearInterval(_iIntervalID); } }, _interval); } return this; } $("table.syntaxhighlighter").wait(function() { $('table.syntaxhighlighter').append("<p class='cnblogs_code_footer'><span class='cnblogs_code_footer_icon'></span></p>"); }); $(document).on("click", ".cnblogs_code_footer",function(){ $(this).parents('table.syntaxhighlighter').css('display','inline-table');$(this).hide(); }); $('.nphpQianCont').viewer({navbar:true,title:false,toolbar:false,movable:false,viewed:function(){$('img').click(function(){$('.viewer-close').trigger('click');});}}); </script></body><!-- Matomo --><script> var _paq = window._paq = window._paq || []; /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() { var u="https://tongji.php.cn/"; _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', '9']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); })(); </script><!-- End Matomo Code --></html>