본문 바로가기
데이터 엔지니어링(DE)/파이썬 활용

HTML / CSS / J.S Web Scraping, Web crawling

by kiimy 2021. 7. 21.
728x90
728x90

* 학습목표 *

  • 크롤링을 이해하고 설명할 수 있다.
  • 파이썬을 통해서 크롤링을 할 수 있다.
  • HTML 혹은 CSS 를 읽을 수 있다.
  • DOM 에 대해서 설명할 수 있다.
  • requests 라이브러리를 사용할 수 있다.
  • beautifulsoup 라이브러리를 사용할 수 있다.

 

## code ##

경로를 병합하여 새 경로 생성 os.path.join('C:\Tmp', 'a', 'b')
# "C:\Tmp\a\b"
현재 작업 폴더 얻기 os.getcwd()
# "C:\Temp"

크롤링 (crawling) 혹은 스크레이핑 (scraping) 은 웹 페이지에 있는 데이터를 모으는 작업

scraping - 특정 정보를 가져오는 것이 목적

 

crawling - 인터넷에 있는 사이트들을 인덱싱하는 목적

== > 자동화에 초점이 맞춰져 있고 알아서 돌아가게 함


Web Browser

  • HTML - 어떻게 구성 되있는지 (= 갖다놓고) 뼈대, 틀

웹 페이지가 어떻게 구성이 되어 있어야 하는지 알려주는 마크업 언어

  • CSS - 살을 붙임 (= 꾸미고) 형태, 색

CSS Selector 특정 요소를 선택할 수 있는 방법

  • Type selector: CSS 타입에 따라서 선택할 수 있습니다 (예를 들어 'p', 'div' 등)
  • Class selector: 클래스에 따라 선택할 수 있습니다.
  • Id selector: id 에 따라 선택할 수 있습니다.

이러한 셀렉터들을 활용하게 되면 더 쉽게 원하는 요소들을 선택해 접근할 수가 있습니다.

나중에 DOM 에서도 이러한 셀렉터들을 이용해 원하는 요소들을 가지고 작업할 수가 있습니다.

CSS 상속

<div style="color:red">

      <p>I have no style</p>

</div>

# p 태그는 아무런 스타일이 적용이 되어 있지 않지만 상위 요소인 div 의 영향을 받게됨

CSS 클래스

어떤 특정 요소들의 스타일을 정하고 싶을 때에 사용

- 동시에 여러 개의 요소들에 대한 스타일을 정할 때에는 보통 클래스를 지정해서 상속을 받음

* HTML

<p class="banana">I have a banana class</p>
* CSS

class 접근은 .banana { color:"yellow"; } ## . (점)class

CSS ID

HTML 에서는 클래스뿐만 아닌 ID 도 지정할 수 있다.

이름처럼 ID 는 보통 특정 HTML 요소를 가리킬 때에만 사용!

class와 차이점 : 클래스와 달리 보통 여러 개의 요소에 사용 되지 않는다.

* HTML

<p id="pink">My id is pink</p>
* CSS

id 접근은 #pink { color:"pink"; } #class

 

웹 페이지 문서가 어떻게 표현되는지 알려주는 스타일시트 언어

  • J.S - 동적인것 (= 시킨다) 실행 입력

기본 구성

  • head - 웹사이트에 대한 정보
  • body - 눈에 보이는 영역

# <p> 내용 </p> == 전체를 Element라고 부름

<p> = opening tag

</p> = closing tag

내용 = content

 

<!doctpye html>

<html>
      <head>
            <meta charset='UTF-8'/>

# 빈 줄을 추가하는 <br> 이나 수평으로 줄을 그어주는 <hr>의 경우는 closing tag 필요없음

            <title> 제목</title>
      </head>
      <body>
      </body>

</html>

* process

현 ip주소 --> web browser --> ip주소를 --> 구글서버에 요청(ip주소파일 HTML, CSS, JS)

                          I-> ( 구글서버에서 가져온 ip주소파일 시각화  ) <<<<<<--I

requests 라이브러리

웹 스크레이핑의 가장 기초는 웹과 소통을 하는 것

파이썬에서는 이러한 소통을 편하게 해주는 requests 라이브러리

==> 파이썬에서 HTTP 요청을 보낼 때 거의 표준으로 사용

특히 HTTP 요청을 간단한 메소드를 통해 실행할 수 있도록 짜여졌다는 것이 가장 큰 장점 중 하나

요청

$ pip install requests

 

import requests

requests.get('https://google.com') ==> 구글에 HTTP 요청( get( ) )

정상적으로 작동하면

<Response [200]>

==> <class 'requests.models.Response'>

응답

requests 라이브러리를 통해서 요청을 보냈다면 응답을 받게 됨

앞서 요청을 보냈을 때 돌려받게 되는 객체는 Response 타입으로 requests 라이브러리에서 사용하는 응답 객체

import requests

url = 'https://google.com'

resp = requests.get(url)

==> resp.status_code 응답 성공여부

https://developer.mozilla.org/ko/docs/Web/HTTP/Status ==> HTTP 에서는 응답에 따라 상태 메세지와 번호를 부여

 

상태 코드에 따라 파이썬에서 if 구문으로 확인하는 것보다 다음과 같이 raise_for_status 메소드를

통해서 응답이 성공적이지 않은 경우에 에러를 일으키는 방법이 더 효율적

import requests
from requests.exceptions import HTTPError

url = 'https://google.com'

try:
    resp = requests.get(url)

    resp.raise_for_status()
except HTTPError as Err:
    print('HTTP 에러가 발생했습니다.')
except Exception as Err:
    print('다른 에러가 발생했습니다.')
else:
    print('성공')

가장 기초는 서버와 통신해서 웹 페이지를 일단 받아올 수 있어야하고 만약에,

에러가 발생하거나 문제가 발생하면 어떤 문제인지 확인하고 제대로 응답이 성공적일 때까지

확인하는 것이 크롤링의 기본

응답 내용

먼저 웹 브라우저를 통해 웹 페이지에 접속하게 되면 보이게 되는 HTML 은 사실 브라우저에서

뒷작업을 거치면서 보여지게 되는 겁니다. 그러나 본질은 HTML, CSS 등 문서 파일이라는 것은 변함이 없습니다.

웹 브라우저가 받는 동일한 HTML 문서를 받을 수도 있습니다.

물론 이것 뿐만 아니라 서버에서 보내주는 데이터도 받을 수도 있습니다.

 

* resp.text = '<!doctype html>.....................</html>'

Response 객체에는 'text' 라는 속성이 존재합니다. 이 속성은 서버에서 받은 응답을 텍스트 형식으로 보여주게 됩니다. 서버에서 받게 되는 응답의 데이터는 사실 바이트 (bytes) 로 받게 됩니다.

따라서 해당 데이터를 텍스트로 인지하기 위해서는 알맞게 디코딩 작업을 거쳐야 합니다.

# 특정 인코딩 방식을 정하고 싶다면 encoding 속성을 설정

BeautifulSoup 라이브러리

-받아온 HTML 파일을 파싱해서 원하는 정보 쉽게 찾을 수 있도록 해줌

 

웹 스크레이핑에서는 서버에 요청을 보내고 응답을 받는 것

돌려받은 응답 내용을 파싱하고 정보를 얻어낼 수 있어야 합니다.

$ pip install beautifulsoup4

 

import requests

from bs4 import BeautifulSoup

 

url = 'https://google.com'

page = requests.get(url)

soup = BeautifulSoup(page.content, 'html.parser')

requests 라이브러리로 먼저 파싱할 페이지를 받아온 뒤에 내용물을 문자열로 변환한
page.content를 인수로 넘기고 어떻게 파싱할 것인지 정함

html.parser는 파이썬 기본 라이브러리에 포함이 되어 있기 때문에 별도로 설치 X
XML 문서나 다른 HTML 파서 (예를 들어html5lib) 등을 사용하려면 따로 설치

https://www.crummy.com/software/BeautifulSoup/bs4/doc/  = Document

파싱할 문자열과 어떻게 파싱할 것인지를 정합니다. 기본적으로 사용할 수 있는 파서는 'html.parser'

파싱 (parsing) 이란??

문자열로 구성된 특정 문서들 (HTML, XML) 등을 파이썬에서도

쉽게 사용할 수 있도록 변환해주는 작업

요소 찾기

find 및 find_all

기본적인 id, class, tag 등의 특징들과 findfind_all 메소드를 이용해 찾아내는 방법

 

find 와 같은 경우에는 조건에 일치하는 첫번째 결과를 리턴하고

find_all 은 조건에 일치하는 모든 결과를 리스트에 담아 리턴

* find

dog_element = soup.find(id='dog')

* find_all

cat_elements = soup.find_all(class_='cat')

위 코드에서 찾은 결과물들을 이용해 다시 세부적으로 검색

for cat_el in cat_elements:

         cat_el.find(class_='fish')

id 는 주로 한번만 사용이 되기 때문에 find 를 사용
class 를 이용해 찾을 때에는class 가 아닌 뒤에 밑줄 '_' 을 추가
==> 추가하지 않게 되는 경우에는 파이썬의 class 로 인식

태그 활용

상세하게 찾고 싶을 때에는 태그와 함께 조합해서 사용

예를 들어 'cat' 이라는 클래스가 'div' 태그에도 있고 'p' 태그에도 있다고 가정

이 떄 'div' 태그를 사용하는 요소를 가지고 올 때

cat_div_elements = soup.find_all('div', class_='cat')

string 활용(= 각 요소의 .string 속성을 불러오는 것이기 때문에 요소가 아닌 문자열로 리턴)

어떤 글이 들어가 있는지 정하고 싶을 때 'raining' 이라는 문자열이 포함되어 있는 요소를 찾고 싶다면

soup.find_all(string='raining')

 

하나의 요소로 받기 위해서는 태그도 같이 추가(요소가 아닌 문자열로 리턴하기 때문에)

soup.find_all('h3', string='raining')

위 코드의 장점이자 단점은 명시한 문자열을 그대로 찾는다는 것
즉, 정확히 'raining' 이라는 문자열을 포함하는지 확인
만약에 대소문자를 잘못 적었거나 띄어쓰기를 실수했다해도 동일한 문자열을 포함한 요소

익명 함수를 활용해서 'raining' 이 대소문자 구분없이 들어가 있는 것을 찾고 싶다면

soup.find_all(string=lambda text: 'raining' in text.lower())

정보 얻기

기본적으로 text 속성을 이용해서 내부 문자를 얻어낼 수 있다.

다음과 같은 HTML 에서 'p' 태그 내부 글을 얻으려면 text 속성을 사용

<p class='cat'>This is a p-cat</p>

 

cat_el = soup.find('p', class_='cat')

cat_el.text

#=> 'This is a p-cat'

 

때에 따라 불필요한 띄어쓰기가 있을 수 있습니다.

그럴 때에는 파이썬의 strip 메소드를 사용해서 정리해줄 수 있습니다.

==> <br> 이나 수평으로 줄을 그어주는 <hr>의 경우는 closing tag 필요없음

        그래서 이 다음에 있는 text를 가져오려면 text.strip() 사용

cat_el.text.strip()

728x90

'데이터 엔지니어링(DE) > 파이썬 활용' 카테고리의 다른 글

DataBase / ORM SQLalchemy / session  (0) 2021.07.24
DOM( Document Object Model )  (0) 2021.07.21

댓글