이제 web scraping에 대해 공부를 해보자.
web scraping은 특정 데이터를 web link에 들어가서 모두 긁어 오는 것을 말한다.
간단한 web scraping은 프로그램을 사용할 수 있고, 복잡한 web scraping은 직접 code를 짜야 한다.
프로그램을 사용한 web scraping은 엄청 단순한 web scraping만 할 수 있다.
web scraping의 대표적인 프로그램인 ScrapeStorm으로 설명을 하겠다.
ScrapeStorm 화면에 web scraping을 할 url 주소를 입력해주자.
나는 coupang의 남성패션 페이지 url 주소를 입력해주겠다.
흔히 보이는 쿠팡의 화면이다.
이 url 주소를 ScrapeStorm 에 입력하면 표 형식으로 데이터를 정리해준다.
그런데 단점이 있다.
첫번째는 상세한 web scraping이 안된다는 점이다.
만약 내가 1행에 있는 '크록스 키즈 크록스' 상품의 리뷰를 web scraping 하고 싶어도, ScrapeStorm에는 그런 기능이 없다.
두번째는 하루 web scraping 양이 정해져 있다.
하루에 100행까지 web scraping 하는 것이 무료이다. 추가로 web scraping 하려면 돈을 지불해야 한다.
그래서 귀찮아도 직접 code를 짜는 것이 좋다.
그러면 직접 code를 짜기 전에 나 혼자 web의 html 코드를 분석할 수 있어야 한다.
보통 web site는 HTML, CSS, JavaScript로 만들어져 있다.
HTML | web site의 뼈대 데이터의 위치를 조정해줌. 어떤 데이터가 어느 위치에 있어야 하는지 정해줌 |
CSS | html이 만든 뼈대 위에 디자인을 해줌. 폰트의 크기 / 색깔 등등 |
JavaScript | 웹사이트의 동작 다른 페이지로 넘어갈 때 어떻게 동작할지 구성 |
web site의 HTML code를 보려면 web page에서 우클릭 후, 페이지 소스 보기 or Ctrl+Shift+i 누르면 된다.
web site는 HTML code로 이루어져 있으므로 HTML의 Tag가 어떤 것이 있는지 살펴보자.
이건 외우지 않아도 되는 항목이다. 그냥 어떤 Tag가 있는지 알고 있으면 된다.
<html> // html 형식으로 된 web page를 만드는 Tag
<head> // web page 상단의 page 이름을 지정해주는 Tag
<title>
이곳에 쓰이는 문장이 page 제목이 되는 것이다.
</title>
head Tag에는 보통 각종 setting 관련 code가 들어온다.
web scraping 할 때는 자세히 안봐도 된다.
1. 외부 css/js file 연결 code
2. 외부 이미지 file을 바탕으로 favicon setting
3. Google analytics와 같은 도구를 위한 JS 코드 연결
</head>
<body> // web scraping 할 때 유심히 봐야하는 Tag / 뼈대를 세우는 code가 있는 Tag
<div> // 구역을 만드는 Tag
<div> // 보통 이렇게 구역 안에 구역이 있다. 이 안쪽에 진짜 본론 내용이 숨겨져 있다.
<h2> // headline의 약자. 1이 제일 크고 6이 제일 작다. 제목 표현의 Tag
</h2>
<p> // paragraph의 약자. 줄글(문단)을 만드는 Tag
강조하는 단어는 <b>굵게 표시</b>를 넣거나 <strong>같은 뜻</strong>을 쓴다.
</p>
<a href=’http://www.naver.com’> // anchor의 약자. 링크를 넣을 때 쓰는 Tag
href는 hyperlink reference의 약자이다.
</a>
<img src=’이미지 링크’ style = “width:20%;”>
src는 sorce의 약자.
</img>
<ol> ordered list >> 자동으로 문장 앞에 번호가 붙음
<li>first list item</li> >> 1.first list item
<li>second list item</li> >> 2.second list item
<li>third list item</li> >> 3.third list item
</ol>
<ul> unordered list >> 번호 없이 문장 앞에 점만 붙음
주로 ul 태그를 많이 사용함
<li class=”main-p” id=”first-p”>first list item</li>
<li class=”main-p” id=”first-p”>first list item</li> >> ᆞfirst list item
<li class=”main-p”>second list item</li> >> ᆞsecond list item
<li class=”main-p”>third list item</li> >> ᆞthird list item
// class는 동일한 Tag가 여러 개 있지만 id는 서로 다 다르다. 주민등록번호와 같다.
// 하나의 Tag를 꺼내고 싶을 때는 id를 써서 꺼내야 한다.
// web scraping할 때 매우 중요한 내용
<li>third list item</li>
</ul>
</div>
</div>
</body>
</html>
여기서 중요한 것은 Tag의 name과 Tag의 attribute를 구별하는 것이다.
그중에서 attribute의 name이나 value가 뭔지 아는 것이 중요하다.
Tag의 name : html / head / body / div / h2 / a / p / ol / ul / li /img
Tag의 attribute : href / src / style / class / id
Class는 Attribute의 name, ”main-p”는 Attribute의 value
이제 web scraping의 순서를 알아보자.
첫번째는 url 분석이다.
url 주소에는 패턴이 존재한다. 대부분 url 주소 중 '?'를 기준으로 데이터 서버와 입력 데이터를 구분한다.
다음 사전을 예로 들어 설명하겠다.
ht~~//alldic.daum.net/search.do?q=안녕
이때, daum.net의 서버에 search.do라는 함수가 존재하고 q 값을 입력 받으면 return 해줄 것이다.
def search.do(q):
~~~~
return ~~~
패턴을 확인하는 방법은 입력 값을 url 주소에 직접 입력해보는 방법이 가장 좋다.
분석을 한 뒤 url 주소를 하나의 문자열로 묶어준다. 자동화를 위해서 필수다.
URL='https://alldic.daum.net/search.do?q='
두번째는 HTTP Response를 얻는 것이다.
url 주소를 받아서 그 주소에 있는 모든 데이터를 달라고 서버에 요청하고, 받는 것이다.
쉽게 설명하면, 우리가 다음 사전에 '안녕'이라고 검색 했다면 urlopen()함수가 해주는 것이다.
보통 urlopen(URL) 함수를 사용하는데, 기능이 제한되는 것이 있어서 request.get(URL).content 함수를 사용할 수 있다.
세번째는 HTML Source를 얻는 것이다.
urlopen(URL)로 얻어진 HTTP Response에는 어마어마한 데이터가 있다.
그중 우리는 web site를 구성하는 html 코드를 가져와야 web scraping이 된다.
우선 BeautifulSoup()이라는 함수에 HTTP Response을 그대로 넘겨준다.
BeautifulSoup(HTTP Response, ‘html.parser’)
그런데, HTTP Response가 html 형식으로 되어 있으니까 BeautifulSoup에게 html 방식으로 해석해 달라고 html.parse에게 부탁하는 것이다.
BeautifulSoup는 HTTP Response 중에 html에 해당하는 것만 꺼내서 우리에게 주는 것이다.
마지막으로 HTML Tag를 꺼내는 것이다.
우리가 원하는 web site data는 Tag 안에 숨어 있다.
보통 find(‘Tag 이름’, {‘Attr name’ : ‘Attr Value’}) 함수나 find_all(~) 함수를 사용해 찾아낸다.
find( ) 함수는 동일한 Attr name / Value를 사용하는 Tag가 여러개 있으면 그중 첫번째 Tag를 출력한다.
find_all( ) 함수는 여러개의 Tag가 있으면 모두 list로 묶어서 [~,~,~] 출력한다.
하지만 Tag의 문자열을 출력해주는 get_text( ) 함수나 attribute name과 value를 출력해주는 attrs 함수는 find( ) 함수에서만 실행이 된다. 그래서 find_all 함수에서 사용하려면 for문을 돌려야 한다.