본문 바로가기
파이썬 (Python)/크롤링 (Crawling)

파이썬 Python 웹사이트 컨텐츠 크롤링하기

by ★√★ 2021. 1. 30.

안녕하세요, Davey 입니다. 오늘 포스팅 내용은 웹사이트 컨텐츠 크롤링하는 내용입니다. 크롤링을 실제적으로 TEST 및 간단한 코드를 통해서 demostration 해보도록 하겠습니다. 

 

 

그럼, 일단, crawling을 위해서 설치해야 할 Library가 있는데, 그것이 바로, beautifulsoup4 입니다. 기 설치된 분들은 설치하지 않아도 되지만, 설치가 되지 않으신 분들은, 아래 명령문을 통해서, consol 창에서 설치를 해주셔야 합니다. 

 

- pip install beautifulsoup4

 

설치 구문을 입력하게 되면, 아래 같이 설치가 진행이 됩니다. (저는 Posting을 위해서 한번 Uninstall을 하고 나서 했는데, 기 설치된 Libarary 잔해 때문에, 약간은 이상하게 나왔지만, 성공적으로 설치 된 상태입니다.

 


D:\Python_Project>pip install beautifulsoup4 
Collecting beautifulsoup4 
  Downloading https://files.pythonhosted.org/packages/cb/a1/c698cf319e9cfed6b17376281bd0efc6bfc8465698f54170ef60a485ab5d/beautifulsoup4-4.8.2-py3-none-any.whl (106kB) 
     |████████████████████████████████| 112kB 234kB/s 
Requirement already satisfied: soupsieve>=1.2 in c:\users\administrator\anaconda3\lib\site-packages (from beautifulsoup4) (1.9.3) 
Installing collected packages: beautifulsoup4 
Successfully installed beautifulsoup4-4.8.2 

 


 

 아래 Snap shot도 참조 부탁 드립니다.

 

 

 

일단 설치 완료가 되면, 아래와 같이 Crawling 을 하기 위해서 Library를 선언해 주셔야 합니다. 

제가 이번에 선언할 Library는 2개 입니다. urlib 과 BeautilfulSoup 입니다. 

 

 

import urllib.request

# Crawling을 가져 올려는 주소를 읽어서, 그 주소에서 나타나는 HTML 내용을 읽어 오기 위해서 선언


from bs4 import BeautifulSoup

# Crawling 한 내용을 나름대로 분석 하고, 분류 하기 위해서 선언 

 

 

일단, Library를 선언한 후, 기본적으로 설정하고, 입력해야 하는 사항이 있습니다. 

 

 

1. Crawling 할 URL

 

- 아래와 같이 일단 검색하고 싶은 항목을 네이버에서 검색을 하고, 그 검색한 화면에 보여주는 URL을 Copy 해서, 변수 urladdress1에 집어넣어줍니다. 관련 snap shot은 아래와 같습니다.

 

 

 

 

 

2.URL통해 HTML을 읽어 올 수 있는 Code

 

- URL을 입력 받은 변수를 읽어와서, 그 URL에 보여주는 HTML을 다 가져오는 Code를 설정을 합니다. 

 

위 2가지를 실현한 Code는 아래와 같습니다. 

 

import urllib.request
from bs4 import BeautifulSoup

urladdress1 = 'https://search.naver.com/search.naver?where=post&sm=tab_jum&query=%EC%98%81%EC%96%B4%EA%B3%B5%EB%B6%80'

# 검색어를 입력하고 나서 나오는 결과 창의 URL을 받는 변수



htmlcontent1 = urllib.request.urlopen(urladdress1).read()

verification1 = BeautifulSoup(htmlcontent1, 'html.parser')

# urladdress1의 변수에 있는 URL을 이용하여, HTML을 읽어 오는 Code

 

위 코드가 잘 실행이 되고 어떤 결과물을 가지고 오는지에 대해서, 확인 할려면, 아래와 같이 Code를 하나 더 삽입하여 구성해주면 됩니다.

 

 

import urllib.request
from bs4 import BeautifulSoup

urladdress1 = 'https://search.naver.com/search.naver?where=post&sm=tab_jum&query=%EC%98%81%EC%96%B4%EA%B3%B5%EB%B6%80'

# 검색어를 입력하고 나서 나오는 결과 창의 URL을 받는 변수



htmlcontent1 = urllib.request.urlopen(urladdress1).read()

verification1 = BeautifulSoup(htmlcontent1, 'html.parser')

# urladdress1의 변수에 있는 URL을 이용하여, HTML을 읽어 오는 Code



print(verification1)

# 관련 HTML을 다 뿌려줘라 라는 명령어 입니다.

 

 

 

 

 

결과물은 아래와 같이 나오게 됩니다. (너무 양이 많아 아래 일부분만 삽입합니다.)

 

--------------------------------------------------------------------------------------------------

 

https://ssl.pstatic.net/sstatic/search/common/og_v3.png" property="og:image"/>    https://ssl.pstatic.net/sstatic/search/favicon/favicon_191118_pc.ico" rel="shortcut icon"/> https://ssl.pstatic.net/sstatic/search/opensearch-description.https.xml" rel="search" title="Naver" type="application/opensearchdescription+xml">https://ssl.pstatic.net/sstatic/search/pc/css/search1_200326.css" rel="stylesheet" type="text/css"/> https://ssl.pstatic.net/sstatic/search/pc/css/search2_200326.css" rel="stylesheet" type="text/css"/> https://ssl.pstatic.net/sstatic/search/pc/css/api_atcmp_200326.css" rel="stylesheet" type="text/css"/>

SCRIPT

 if (!<a href="String.prototype.trim)" target="_blank">String.prototype.trim)</a> { <a href="String.prototype.trim" target="_blank">String.prototype.trim</a> = function () { return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); }; } if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(searchElement, fromIndex) { var k; if (this == null) { throw new TypeError('"this" is null or not defined'); } var o = Object(this); var len = o.length >>> 0; if (len === 0) { return -1; } var n = fromIndex | 0; if (n >= len) { return -1; } k = <a href="Math.max(n" target="_blank">Math.max(n</a> >= 0 ? n : len - <a href="Math.abs(n)," target="_blank">Math.abs(n),</a> 0); while (k < len) { if (k in o && o[k] === searchElement) { return k; } k++; } return -1; }; } if (typeof(encodeURIComponent) != "function") { encodeURIComponent = function (s) { function toHex (n) { var hexchars = "0123456789ABCDEF" ; return "%%" + <a href="hexchars.charAt(n" target="_blank">hexchars.charAt(n</a>>>4) + <a href="hexchars.charAt(n&0xF)" target="_blank">hexchars.charAt(n&0xF)</a> ; } var es = "" ; for (var i = 0; i < s.length;) { var c = s.charCodeAt(i++) ; if ((c&0xF800) == 0xD800) { var sc = s.charCodeAt(i++) ; c = ((c-0xD800)<<10) + (sc-0xDC00) + 0x10000 ; } if (!(c&~0x7F)) { if ((c>=65&&c<=90) || (c>=97&&c<=122) || (c>=48&&c<=57) || (c>=45&&c<=46) || c==95 || c==33 || c==126 || (c>=39&&c<=42)) es += String.fromCharCode(c) ; else es += toHex(c) ; } else if (!(c&~0x7FF)) es += toHex(0xC0+(c>>6)) + toHex(c&0x3F) ; else if (!(c&~0xFFFF)) es += toHex(0xE0+(c>>12)) + toHex(0x80+(c>>6&0x3F)) + toHex(0x80+(c&0x3F)) ; else es += toHex(0xF0+(c>>18)) + toHex(0x80+(c>>12&0x3F)) + toHex(0x80+(c>>6&0x3F)) + toHex(0x80+(c&0x3F)) ; } return es ; } } naver = <a href="window.naver" target="_blank">window.naver</a> || {}; <a href="naver.search" target="_blank">naver.search</a> = <a href="naver.search" target="_blank">naver.search</a> || {}; var g_D = 0 ; <a href="naver.search.error" target="_blank">naver.search.error</a> = (function () { var errorList = Array() ; return { add : function (s) { <a href="errorList.push(s)" target="_blank">errorList.push(s)</a> ; }, clear : function () { delete errorList ; }, get : function (s) { return errorList ; }, getString : function (d) { if (typeof d === 'undefined') d = '|' ; return <a href="errorList.join(d)" target="_blank">errorList.join(d)</a> ; } } })(); <a href="naver.search.cookie" target="_blank">naver.search.cookie</a> = (function () { return { set : function (key, value, expire, domain) { var cookie = key + "=" + escape(value); if (typeof expire !== 'undefined') { if (expire instanceof Date) { cookie = cookie + "; expires=" + expire.toUTCString(); } else { var exdate = new Date((new Date()).getTime() + expire*1000); cookie = cookie + "; expires=" + exdate.toUTCString(); } } cookie = cookie + "; path=/"; if (domain != null) { cookie = cookie + "; domain=" + domain; } <a href="document.cookie" target="_blank">document.cookie</a> = cookie; }, get : function (key) { var cookie_list = <a href="document.cookie.split(/" target="_blank">document.cookie.split(/</a>\s*;\s*/); for (var i = 0; i < <a href="cookie_list.length;" target="_blank">cookie_list.length;</a> i++) { var tmp_list = cookie_list[i].split("="); var c_key = tmp_list[0].trim(); var c_value = tmp_list[1]; if (key == c_key) { return unescape(c_value); } } return null; } } })(); <a href="naver.search.https" target="_blank">naver.search.https</a> = window.location.protocol == "https:"; <a href="naver.search.meta_referrer" target="_blank">naver.search.meta_referrer</a> = 0; var _nx_js_load = (function () { var scrs = {} ; return function (script, callback) { scrs[script] = {} ; scrs[script].domscript = document.createElement('script'); scrs[script]<a href=".domscript.src" target="_blank">.domscript.src</a> = script ; if (callback) scrs[script].callback = (callback instanceof Array) ? callback : [callback]; scrs[script].domscript.onloadDone = false; scrs[script]<a href=".domscript.onload" target="_blank">.domscript.onload</a> = function() { scrs[script].domscript.onloadDone = true; if (scrs[script].callback) { for (var i = 0; i < scrs[script]<a href=".callback.length;" target="_blank">.callback.length;</a> i++) { scrs[script].callback[i]() ; } } scrs[script]<a href=".domscript.onload" target="_blank">.domscript.onload</a> = scrs[script].domscript.onreadystatechange = null; } ; scrs[script].domscript.onreadystatechange = function() { if ( ("loaded" === scrs[script].domscript.readyState || "complete" === scrs[script].domscript.readyState) && !scrs[script].domscript.onloadDone ) { scrs[script]<a href=".domscript.onload();" target="_blank">.domscript.onload();</a> } } ; document.getElementsByTagName('head')[0].appendChild(scrs[script].domscript); }; })() ; var nx_js_defer_load = (function() { var info = {} ; return function(scrname, callback, t) { var nx_load_once = (function() { return function(scrname) { if (info[scrname].t > 0) setTimeout(function() { _nx_js_load(scrname, info[scrname].callback) ; }, t) ; else _nx_js_load(scrname, info[scrname].callback) ; } ; })(); if (t < 0) t = 0 ; if (info[scrname]) { n = info[scrname].length; for (var i = 0; i < n; i++) { if (info[scrname][i] == callback) return ; } if (t < info[scrname].t) info[scrname].t = t ; } else { info[scrname] = {} ; info[scrname].callback = [] ; info[scrname].t = t ; jindo.$Fn(function() { nx_load_once(scrname) ; }).attach(window, "load") ; } info[scrname]<a href=".callback.push(callback)" target="_blank">.callback.push(callback)</a> ; }; })(); function nx_js_lazyload(scripts, onload, is_serial) { if (!(scripts instanceof Array)) { scripts = [scripts]; } if (is_serial) { function load_next() { if (<a href="scripts.length" target="_blank">scripts.length</a> == 0) { onload(); return; } _nx_js_load( <a href="scripts.shift()," target="_blank">scripts.shift(),</a> load_next ) ; } load_next(); } else { var load_check = function() { var num_js = <a href="scripts.length;" target="_blank">scripts.length;</a> return function() { num_js--; if (num_js <= 0) { onload(); } } }(); for (var i = 0; i < <a href="scripts.length;" target="_blank">scripts.length;</a> i++) { _nx_js_load( scripts[i], load_check ) ; } } } function nx_defer_eval (id) { var codeElement = document.getElementById(id), code = codeElement.innerHTML; eval(code.replace(/\/\*/, '').replace(/\*\//, '')); } 

--------------------------------------------------------------------------------------------------

 

 여기에서, 내용 결과물의 이름과 URL을 가져오는 Code를 삽입해보도록 하겠습니다. Class를 기준으로 가져와야 하기 때문에, Class를 볼 수 있도록 해보도록 하겠습니다. 

 

 해당 "영어 공부" 라는 검색어로 찾은 창에, 마우스 오른쪽 키를 누르고, "검사" 항목을 선택하면, 그 창에 HTML이 보이게 됩니다. (아래 첨부 Snap Shot 참조)

 

 

 

 

그리고, 검색 결과의 이름에 마우스를 가져다가 대면, 해당되는 HTML 문구가 표시가 됩니다. 그 해당항목의 Class를 가져와서, 아래와 같이 Code를 작성하면 됩니다. 변수 이름은 data1로 정하였습니다. 

 

--------------------------------------------------------------------------------------------------

 

import urllib.request
from bs4 import BeautifulSoup

urladdress1 = 'https://search.naver.com/search.naver?where=post&sm=tab_jum&query=%EC%98%81%EC%96%B4%EA%B3%B5%EB%B6%80'

# 검색어를 입력하고 나서 나오는 결과 창의 URL을 받는 변수



htmlcontent1 = urllib.request.urlopen(urladdress1).read()

verification1 = BeautifulSoup(htmlcontent1, 'html.parser')

# urladdress1의 변수에 있는 URL을 이용하여, HTML을 읽어 오는 Code


data1 = verification1.find_all(class_='sh_blog_title')

# 읽어온 HTML에서 필요한 부분에 대한 결과를 얻기 위한 Code

--------------------------------------------------------------------------------------------------

 

 

 
 

print(data1)의 Code를 삽입하면 아래와 같은 결과값을 보실 수 있습니다.

 

--------------------------------------------------------------------------------------------------

 

[https://blog.naver.com/gashwoon?Redirect=Log&logNo=221883021663" onclick="return goOtherCR(this, 'a=blg*i.tit&r=1&i=90000003_0000000000000033A942395F&u='+urlencode(this.href))" target="_blank" title="영어공부혼자하기 내힘으로 열공해요!">영어공부혼자하기 내힘으로 열공해요!, https://blog.naver.com/eng1588?Redirect=Log&logNo=221875372853" onclick="return goOtherCR(this, 'a=blg*i.tit&r=2&i=90000003_0000000000000033A8CD8335&u='+urlencode(this.href))" target="_blank" title="무료 영어공부 방법 베스트 3">무료 영어공부 방법 베스트 3, https://blog.naver.com/abfos?Redirect=Log&logNo=221881523843" onclick="return goOtherCR(this, 'a=blg*i.tit&r=3&i=90000003_0000000000000033A92B5E83&u='+urlencode(this.href))" target="_blank" title="영어공부 다같이 함께해요!">영어공부 다같이 함께해요!, https://blog.naver.com/ell_n?Redirect=Log&logNo=221838520352" onclick="return goOtherCR(this, 'a=blg*i.tit&r=4&i=90000003_0000000000000033A69B3020&u='+urlencode(this.href))" target="_blank" title="기초영어공부 목표를 세웠다면 저처럼!">기초영어공부 목표를 세웠다면 저처럼!, https://kebsz0410.blog.me/221840913966" onclick="return goOtherCR(this, 'a=blg*i.tit&r=5&i=90000003_0000000000000033A6BFB62E&u='+urlencode(this.href))" target="_blank" title="영어공부, 인강과 함께 실력 늘리는 법!">영어공부, 인강과 함께 실력 늘리는 법!, https://blog.naver.com/homashim?Redirect=Log&logNo=221805777339" onclick="return goOtherCR(this, 'a=blg*i.tit&r=6&i=90000003_0000000000000033A4A791BB&u='+urlencode(this.href))" target="_blank" title="영어공부 5개월째 접어들었네요">영어공부 5개월째 접어들었네요, https://blog.naver.com/kii170?Redirect=Log&logNo=221825764102" onclick="return goOtherCR(this, 'a=blg*i.tit&r=7&i=90000003_0000000000000033A5D88B06&u='+urlencode(this.href))" target="_blank" title="몰타어학연수 지친 현대인들을 위해 힐링과 영어공부를 동시에!">몰타어학연수 지친 현대인들을 위해 힐링과 영어공부를 동시에!, http://lukelookenglish.com/221847211426" onclick="return goOtherCR(this, 'a=blg*i.tit&r=8&i=90000003_0000000000000033A71FCDA2&u='+urlencode(this.href))" target="_blank" title="★코로나시대에 영어공부 | 룩룩잉글리쉬 ★">★코로나시대에 영어공부 | 룩룩잉글리쉬 ★, https://blog.naver.com/redpassion17?Redirect=Log&logNo=221829484323" onclick="return goOtherCR(this, 'a=blg*i.tit&r=9&i=90000003_0000000000000033A6114F23&u='+urlencode(this.href))" target="_blank" title="[인턴100번보기 오픈채팅 모집] 영화로 영어공부하기16주차 공부일기">오픈채팅 모집] 영화로 영어공부하기16주차 공부일기, https://blog.naver.com/tobemaven?Redirect=Log&logNo=221854960740" onclick="return goOtherCR(this, 'a=blg*i.tit&r=10&i=90000003_0000000000000033A7960C64&u='+urlencode(this.href))" target="_blank" title="오르테가 박재범 영어공부2탄_모욕하다, 내가 아는바로는, 지어내다, 정신차리다">오르테가 박재범 영어공부2탄_모욕하다, 내가 아는바로는...] 

 

--------------------------------------------------------------------------------------------------

 

위 항목은 검색어를 통해 찾은 웹페이지의 첫번째 페이지에 대한 결과물을 가져온 것 입니다. 

 

그런데, 너무 번잡하기 때문에, 이 내용 중에, 이름과 URL만 보기 좋게 가져오는 Code를 삽입해보도록 하겠습니다.

다시 전체 코드에서 필요한 코드를 삽입하면 아래와 같습니다. 

 

 

import urllib.request
from bs4 import BeautifulSoup

urladdress1 = 'https://search.naver.com/search.naver?where=post&sm=tab_jum&query=%EC%98%81%EC%96%B4%EA%B3%B5%EB%B6%80'

# 검색어를 입력하고 나서 나오는 결과 창의 URL을 받는 변수



htmlcontent1 = urllib.request.urlopen(urladdress1).read()

verification1 = BeautifulSoup(htmlcontent1, 'html.parser')

# urladdress1의 변수에 있는 URL을 이용하여, HTML을 읽어 오는 Code


data1 = verification1.find_all(class_='sh_blog_title')

# 읽어온 HTML에서 필요한 부분에 대한 결과를 얻기 위한 Code


for item in data1: # 각 항목을 다 뿌지리 말고, 그 내용중에 하나 하나 씩 결과물 가져오기 위한 반복문
print(item.attrs['title']) # 속성값 중에 Title 가져오기
print(item.attrs['href']) # 속성값 중에 URL 가져오기
print() # 결과 내용 사이 사이에 빈칸을 두기

 

코드 작성 후 실행하면 아래와 같습니다. 아래와 같이 깔끔하게 정리되는 걸 보실 수 있습니다.

 

--------------------------------------------------------------------------------------------------

 

영어공부혼자하기 내힘으로 열공해요! 
https://blog.naver.com/gashwoon?Redirect=Log&logNo=221883021663 

무료 영어공부 방법 베스트 3 
https://blog.naver.com/eng1588?Redirect=Log&logNo=221875372853 

영어공부 다같이 함께해요! 
https://blog.naver.com/abfos?Redirect=Log&logNo=221881523843 

기초영어공부 목표를 세웠다면 저처럼! 
https://blog.naver.com/ell_n?Redirect=Log&logNo=221838520352 

영어공부, 인강과 함께 실력 늘리는 법! 
https://kebsz0410.blog.me/221840913966 

영어공부 5개월째 접어들었네요 
https://blog.naver.com/homashim?Redirect=Log&logNo=221805777339 

몰타어학연수 지친 현대인들을 위해 힐링과 영어공부를 동시에! 
https://blog.naver.com/kii170?Redirect=Log&logNo=221825764102 

★코로나시대에 영어공부 | 룩룩잉글리쉬 ★ 
http://lukelookenglish.com/221847211426 

[인턴100번보기 오픈채팅 모집] 영화로 영어공부하기16주차 공부일기 
https://blog.naver.com/redpassion17?Redirect=Log&logNo=221829484323 

오르테가 박재범 영어공부2탄_모욕하다, 내가 아는바로는, 지어내다, 정신차리다 
https://blog.naver.com/tobemaven?Redirect=Log&logNo=221854960740

 

--------------------------------------------------------------------------------------------------

 

이상입니다.

 

제 Posting이 조금이나마 정보 전달에 도움이 되셨길 빌며, 되셨다면, 구독, 댓글, 공감 3종 세트 부탁 드립니다. 감사합니다.


[저작권이나, 권리를 침해한 사항이 있으면 언제든지 Comment 부탁 드립니다. 검토 후 수정 및 삭제 조치 하도록 하겠습니다. 그리고, 기재되는 내용은 개인적으로 습득한 내용이므로, 혹 오류가 발생할 수 있을 가능성이 있으므로, 기재된 내용은 참조용으로만 봐주시길 바랍니다. 게시물에, 오류가 있을때도, Comment 달아 주시면, 검증 결과를 통해, 수정하도록 하겠습니다.]

 

728x90

댓글


// 내부링크를 현재창으로 열기 // Open internal links in same tab