>  기사  >  백엔드 개발  >  스크래퍼 경쟁자

스크래퍼 경쟁자

Barbara Streisand
Barbara Streisand원래의
2024-11-06 15:21:03930검색

Scrapper Concorrente

프로그램 목표

동시에 웹페이지에 접속하여 각 페이지의 제목을 추출하고 해당 제목을 터미널에 표시합니다. 이는 Go의 동시성을 사용하여 수행되며, 이를 통해 여러 페이지에 동시에 액세스하여 시간을 절약할 수 있습니다.

코드 설명

사용된 패키지

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

fetchTitle 함수

이 역할은 다음을 담당합니다.

  • 웹페이지(URL) 접속
  • 페이지 제목 추출
  • 결과를 채널로 전달
func fetchTitle(url string, wg *sync.WaitGroup, results chan<- string) {
    defer wg.Done() // Marca a goroutine como concluída no WaitGroup

기능 매개변수:

  • url 문자열: 제목을 얻기 위해 접속하려는 웹페이지(url)의 주소를 나타냅니다
  • wg *sync.WaitGroup: 동시에 실행 중인 모든 작업(고루틴)의 완료를 동기화하는 데 사용하는 WaitGroup에 대한 포인터입니다. *는 "주소"를 WaitGroup`에 전달하는 것이지 복사본이 아님을 나타냅니다.
  • results chan<- string: 프로그램의 다른 부분으로 문자열을 보낼 수 있는 단방향 채널입니다. 결과(제목 또는 오류 메시지)를 기본 함수에 전달하는 데 사용됩니다.

defer wg.Done() 라인은 fetchTitle 함수가 완료되면 이 작업(고루틴)을 완료된 것으로 표시하도록 프로그램에 지시합니다. 이는 모든 작업이 언제 완료되었는지 Main이 알 수 있도록 중요합니다.

HTTP 요청


요청, 오류 := http.Get(url)
오류가 있는 경우 != nil {
결과 <- fmt.Sprintf("%s 액세스 오류: %v", url, err)
복귀
}
요청 연기.Body.Close()

  • http.Get(url): 이 줄은 URL에 HTTP GET 요청을 보냅니다. 이는 우리가 페이지에 액세스하여 서버에 해당 콘텐츠를 요청하고 있음을 의미합니다.
  • err != nil: 여기에서는 페이지에 액세스할 때 오류가 있었는지 확인합니다(예: 페이지가 존재하지 않거나 서버가 응답하지 않는 경우). 오류가 있으면 결과 채널에 메시지를 보내고 반환으로 기능을 종료합니다.
  • defer req.Body.Close(): 이렇게 하면 페이지 콘텐츠 사용을 마친 후 이를 저장하기 위해 할당된 메모리를 확보할 수 있습니다.

상태 확인


req.StatusCode != 200인 경우 {
결과 <- fmt.Sprintf("%s 액세스 오류: 상태 %d %s", url, req.StatusCode, req.Status)
복귀
}

  • req.StatusCode != 200: 서버가 200 OK 코드로 응답했는지 확인합니다(성공을 나타냄). 200이 아니면 페이지가 제대로 로드되지 않은 것입니다. 그런 다음 결과 채널에 오류 메시지를 보내고 기능을 종료합니다.

타이틀 로딩 및 검색


doc, err := goquery.NewDocumentFromReader(req.Body)
오류가 있는 경우 != nil {
결과 <- fmt.Sprintf("%s에서 문서를 로드하는 중 오류 발생: %v", url, err)
복귀
}
title := doc.Find("title").Text()
결과 <- fmt.Sprintf("%s의 제목: %s", url, title)
}

  • goquery.NewDocumentFromReader(req.Body): 페이지의 HTML 콘텐츠(req.Body에서 제공)를 goquery에 로드합니다. 이를 통해 HTML의 특정 부분을 탐색하고 검색할 수 있습니다.
  • doc.Find("title").Text(): 태그를 찾습니다. 페이지의 HTML에서 내부 텍스트(예: 제목)를 가져옵니다. </pre> <li> <strong>results <- fmt.Sprintf("Título de %s: %s", url, title)</strong>: 추출된 제목을 나중에 읽을 수 있는 결과 채널로 보냅니다.</li> <h2> 주요 기능 </h2> <p>메인 기능은 프로그램을 구성하고 제어하는 ​​주요 기능입니다.</p> <p><br> func 메인() {<br> urls := []문자열{<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>: 처리하려는 URL 목록을 정의합니다. 각 URL은 페이지 제목을 추출하는 고루틴으로 전달됩니다.</li> </ul> <h2> WaitGroup 및 채널 구성 </h2> <p><br> var wg sync.WaitGroup<br> results := make(chan string, len(urls)) // 결과를 저장할 채널<br> </p> <ul> <li> <strong>var wg sync.WaitGroup</strong>: 고루틴 수를 제어하고 프로그램이 끝나기 전에 고루틴이 모두 완료되도록 하는 WaitGroup의 새 인스턴스를 생성합니다.</li> <li> <strong>results := make(chan string, len(urls))</strong>: URL 수와 동일한 용량의 결과 채널을 만듭니다. 이 채널은 제목이나 오류가 있는 메시지를 저장합니다.</li> </ul> <h2> 고루틴의 홈 </h2> <p><br> for _, url := 범위 URL {<br> wg.추가(1)<br> fetchTitle(url, &wg, 결과)로 이동<br> }<br> </p> <ul> <li> <strong>for _, url := range urls</strong>: 여기에서는 목록의 각 URL을 반복합니다.</li> <li> <strong>wg.Add(1)</strong>: 각 URL에 대해 WaitGroup 카운터를 증가시켜 새 작업(고루틴)이 시작됨을 나타냅니다.</li> <li> <strong>go fetchTitle(url, &wg, results)</strong>: 각 URL에 대해 fetchTitle을 <strong>goroutine</strong>으로 호출합니다. 즉, 다른 URL과 병렬로 실행되도록 합니다.</li> </ul> <h2> 대기 및 결과 표시 </h2> <p><br> wg.잠깐()<br> 닫기(결과)<br> </p> <hr> <p>REPO: https://github.com/ionnss/Scrapper-GoRoutine</p> <hr> <p>이온,</p> <p>또 지구의 날</p> <p>위 내용은 스크래퍼 경쟁자의 상세 내용입니다. 자세한 내용은 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>성명:</span><div>본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.</div></div></div><div class="nphpSytBox"><span>이전 기사:<a class="dBlack" title="C#에서 Go까지: AES 및 Base64 인코딩 호환성 달성" href="http://m.php.cn/ko/faq/1796672826.html">C#에서 Go까지: AES 및 Base64 인코딩 호환성 달성</a></span><span>다음 기사:<a class="dBlack" title="C#에서 Go까지: AES 및 Base64 인코딩 호환성 달성" href="http://m.php.cn/ko/faq/1796672838.html">C#에서 Go까지: AES 및 Base64 인코딩 호환성 달성</a></span></div><div class="nphpSytBox2"><div class="nphpZbktTitle"><h2>관련 기사</h2><em><a href="http://m.php.cn/ko/article.html" class="bBlack"><i>더보기</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="http://m.php.cn/ko/faq/1796672954.html" title="바둑을 배우는 나의 여정을 따라오세요" class="aBlack">바둑을 배우는 나의 여정을 따라오세요</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/ko/faq/1796673085.html" title="Go에서 특정 오류를 어떻게 캡처합니까?" class="aBlack">Go에서 특정 오류를 어떻게 캡처합니까?</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/ko/faq/1796673104.html" title="Go는 전통적인 메커니즘 없이 어떻게 다형성을 달성합니까?" class="aBlack">Go는 전통적인 메커니즘 없이 어떻게 다형성을 달성합니까?</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/ko/faq/1796672838.html" title="Go 템플릿에서 문자열을 효율적으로 연결하는 방법은 무엇입니까?" class="aBlack">Go 템플릿에서 문자열을 효율적으로 연결하는 방법은 무엇입니까?</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/ko/faq/1796672890.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><div class="nphpFoot"><div class="nphpFootBg"><ul class="nphpFootMenu"><li><a href="http://m.php.cn/ko/"><b class="icon1"></b><p>집</p></a></li><li><a href="http://m.php.cn/ko/course.html"><b class="icon2"></b><p>강의</p></a></li><li><a href="http://m.php.cn/ko/wenda.html"><b class="icon4"></b><p>Q&A</p></a></li><li><a href="http://m.php.cn/ko/login"><b class="icon5"></b><p>나의</p></a></li><div class="clear"></div></ul></div></div><div class="nphpYouBox" style="display: none;"><div class="nphpYouBg"><div class="nphpYouTitle"><span onclick="$('.nphpYouBox').hide()"></span><a href="http://m.php.cn/ko/"></a><div class="clear"></div></div><ul class="nphpYouList"><li><a href="http://m.php.cn/ko/"><b class="icon1"></b><span>집</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/course.html"><b class="icon2"></b><span>강의</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/article.html"><b class="icon3"></b><span>기사</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/wenda.html"><b class="icon4"></b><span>Q&A</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/dic.html"><b class="icon6"></b><span>사전</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/course/type/99.html"><b class="icon7"></b><span>수동</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/xiazai/"><b class="icon8"></b><span>다운로드</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/faq/zt" title="주제"><b class="icon12"></b><span>주제</span><div class="clear"></div></a></li><div class="clear"></div></ul></div></div><div class="nphpDing" style="display: none;"><div class="nphpDinglogo"><a href="http://m.php.cn/ko/"></a></div><div class="nphpNavIn1"><div class="swiper-container nphpNavSwiper1"><div class="swiper-wrapper"><div class="swiper-slide"><a href="http://m.php.cn/ko/" >집</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/article.html" class="hover">기사</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/wenda.html" >Q&A</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/course.html" >강의</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/faq/zt" >주제</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/xiazai" >다운로드</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/game" >게임</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/dic.html" >사전</a></div><div class="clear"></div></div></div><div class="langadivs" ><a href="javascript:;" class="bg4 bglanguage"></a><div class="langadiv" ><a onclick="javascript:setlang('zh-cn');" class="language course-right-orders chooselan " href="javascript:;"><span>简体中文</span><span>(ZH-CN)</span></a><a onclick="javascript:setlang('en');" class="language course-right-orders chooselan " href="javascript:;"><span>English</span><span>(EN)</span></a><a onclick="javascript:setlang('zh-tw');" class="language course-right-orders chooselan " href="javascript:;"><span>繁体中文</span><span>(ZH-TW)</span></a><a onclick="javascript:setlang('ja');" class="language course-right-orders chooselan " href="javascript:;"><span>日本語</span><span>(JA)</span></a><a onclick="javascript:;" class="language course-right-orders chooselan chooselanguage" href="javascript:;"><span>한국어</span><span>(KO)</span></a><a onclick="javascript:setlang('ms');" class="language course-right-orders chooselan " href="javascript:;"><span>Melayu</span><span>(MS)</span></a><a onclick="javascript:setlang('fr');" class="language course-right-orders chooselan " href="javascript:;"><span>Français</span><span>(FR)</span></a><a onclick="javascript:setlang('de');" class="language course-right-orders chooselan " href="javascript:;"><span>Deutsch</span><span>(DE)</span></a></div></div><script> var swiper = new Swiper('.nphpNavSwiper1', { slidesPerView : 'auto', observer: true,//修改swiper自己或子元素时,自动初始化swiper observeParents: true,//修改swiper的父元素时,自动初始化swiper }); </script></div></div><!--顶部导航 end--><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></html>