Maison >développement back-end >Golang >Concurrent Scrapper

Concurrent Scrapper

Barbara Streisand
Barbara Streisandoriginal
2024-11-06 15:21:031043parcourir

Scrapper Concorrente

Objectif du programme

Accédez aux pages web en même temps pour extraire le titre de chaque page et afficher ces titres dans le terminal. Cela se fait grâce à la concurrence dans Go, qui vous permet d'accéder à plusieurs pages simultanément, ce qui vous fait gagner du temps.

Explication du Code

Forfaits utilisés

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

fonction fetchTitle

Ce rôle est responsable de :

  • Accéder à une page Web (url)
  • Extraire le titre de la page
  • Evnier le résultat sur une chaîne
func fetchTitle(url string, wg *sync.WaitGroup, results chan<- string) {
    defer wg.Done() // Marca a goroutine como concluída no WaitGroup

Paramètres de fonction :

  • chaîne d'url : Représente l'adresse de la page web (url) à laquelle nous allons accéder pour obtenir le titre
  • wg *sync.WaitGroup : pointeur vers un WaitGroup, que nous utilisons pour synchroniser l'achèvement de toutes les tâches (goroutines) qui s'exécutent en même temps. Le * indique que nous transmettons une "adresse" à WaitGroup` et non une copie de celle-ci.
  • results chan<- string : Il s'agit d'un canal unidirectionnel qui vous permet d'envoyer des chaînes à une autre partie du programme. Il permet de transmettre des résultats (titres ou messages d'erreur) à la fonction principale

La ligne defer wg.Done() indique au programme de marquer cette tâche (goroutine) comme terminée lorsque la fonction fetchTitle se termine. Ceci est important pour que le principal sache quand toutes les tâches sont terminées.

Requête HTTP


req, err := http.Get(url)
si erreur != nul {
résultats <- fmt.Sprintf("Erreur d'accès à %s : %v", url, err)
revenir
>
différer req.Body.Close()

  • http.Get(url) : Cette ligne effectue une requête HTTP GET à l'URL. Cela signifie que nous accédons à la page et demandons au serveur son contenu.
  • err != nil : Ici, nous vérifions s'il y a eu une erreur lors de l'accès à la page (par exemple, si la page n'existe pas ou si le serveur ne répond pas). S'il y a une erreur, nous envoyons un message au canal de résultats et terminons la fonction avec return.
  • defer req.Body.Close() : Cela garantit qu'une fois que nous avons fini d'utiliser le contenu de la page, nous libérons la mémoire allouée pour le stocker.

Vérification de l'état


si req.StatusCode != 200 {
résultats <- fmt.Sprintf("Erreur d'accès à %s : statut %d %s", url, req.StatusCode, req.Status)
revenir
>

  • req.StatusCode != 200 : On vérifie si le serveur a répondu avec le code 200 OK (indique le succès). Si ce n’est pas 200, cela signifie que la page ne s’est pas chargée correctement. Nous envoyons ensuite un message d'erreur au canal de résultats et terminons la fonction.

Chargement et recherche de titre


doc, err := goquery.NewDocumentFromReader(req.Body)
si erreur != nul {
résultats <- fmt.Sprintf("Erreur lors du chargement du document à partir de %s : %v", url, err)
revenir
>
titre := doc.Find("titre").Text()
résultats <- fmt.Sprintf("Titre de %s : %s", url, titre)
>

  • goquery.NewDocumentFromReader(req.Body) : Nous chargeons le contenu HTML de la page (fourni par req.Body) dans goquery, ce qui vous permet de naviguer et de rechercher des parties spécifiques du HTML.
  • doc.Find("title").Text() : On recherche la balise dans le HTML de la page et récupérez le texte à l'intérieur (c'est-à-dire le titre). </pre> <li> <strong>results <- fmt.Sprintf("Título de %s: %s", url, title)</strong> : Nous envoyons le titre extrait au canal des résultats, où il sera lu plus tard.</li> <h2> fonction principale </h2> <p>La fonction principale est la fonction principale qui configure et contrôle le programme.</p> <p><br> func main() {<br> URL := []chaîne{<br> "http://olos.novagne.com.br/Olos/login.aspx?logout=true",<br> "http://sistema.novagne.com.br/novagne/",<br> ><br> </p> <ul> <li> <strong>urls := []string{...}</strong> : Nous définissons une liste d'URL que nous souhaitons traiter. Chaque URL sera transmise à une goroutine qui extraira le titre de la page.</li> </ul> <h2> Configuration du groupe d'attente et des canaux </h2> <p><br> var wg sync.WaitGroup<br> results := make(chan string, len(urls)) // Canal pour stocker les résultats<br> </p> <ul> <li> <strong>var wg sync.WaitGroup</strong> : Nous créons une nouvelle instance de WaitGroup, qui contrôlera le nombre de goroutines et garantira qu'elles se terminent toutes avant la fin du programme.</li> <li> <strong>results := make(chan string, len(urls))</strong> : Nous créons un canal de résultats d'une capacité égale au nombre d'URL. Ce canal stockera les messages avec des titres ou des erreurs.</li> </ul> <h2> La maison des Goroutines </h2> <p><br> pour _, url := plage d'URL {<br> wg.Add(1)<br> allez chercherTitle(url, &wg, résultats)<br> ><br> </p> <ul> <li> <strong>pour _, url := plage d'urls</strong> : Ici, nous parcourons chaque URL de la liste.</li> <li> <strong>wg.Add(1)</strong> : Pour chaque URL, nous incrémentons le compteur WaitGroup pour indiquer qu'une nouvelle tâche (goroutine) va être démarrée.</li> <li> <strong>go fetchTitle(url, &wg, results)</strong> : Nous appelons fetchTitle comme une <strong>goroutine</strong> pour chaque URL, c'est-à-dire que nous la faisons fonctionner en parallèle avec les autres.</li> </ul> <h2> Attente et affichage des résultats </h2> <p><br> wg.Attendez()<br> fermer(résultats)<br> </p> <hr> <p>REPO : https://github.com/ionnss/Scrapper-GoRoutine</p> <hr> <p>ions,</p> <p>un autre jour de la terre</p> <p>Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!</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>Déclaration:</span><div>Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn</div></div></div><div class="nphpSytBox"><span>Article précédent:<a class="dBlack" title="De C# à Go : atteindre la compatibilité des codages AES et Base64" href="https://m.php.cn/fr/faq/1796672826.html">De C# à Go : atteindre la compatibilité des codages AES et Base64</a></span><span>Article suivant:<a class="dBlack" title="De C# à Go : atteindre la compatibilité des codages AES et Base64" href="https://m.php.cn/fr/faq/1796672838.html">De C# à Go : atteindre la compatibilité des codages AES et Base64</a></span></div><div class="nphpSytBox2"><div class="nphpZbktTitle"><h2>Articles Liés</h2><em><a href="https://m.php.cn/fr/article.html" class="bBlack"><i>Voir plus</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/fr/faq/419133.html" title="Qu'est-ce que le langage Go ? Introduction aux avantages et inconvénients du langage Go" class="aBlack">Qu'est-ce que le langage Go ? Introduction aux avantages et inconvénients du langage Go</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/fr/faq/419289.html" title="Que signifie le gin ?" class="aBlack">Que signifie le gin ?</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/fr/faq/421167.html" title="Pourquoi Go est-il plus performant que PHP ?" class="aBlack">Pourquoi Go est-il plus performant que PHP ?</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/fr/faq/421591.html" title="À quoi convient le langage go ?" class="aBlack">À quoi convient le langage go ?</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/fr/faq/422570.html" title="aller aux bases du langage" class="aBlack">aller aux bases du langage</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>Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!</p></div><div class="footermid"><a href="https://m.php.cn/fr/about/us.html">À propos de nous</a><a href="https://m.php.cn/fr/about/disclaimer.html">Clause de non-responsabilité</a><a href="https://m.php.cn/fr/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>