* 학습목표 *
- 크롤링을 이해하고 설명할 수 있다.
- 파이썬을 통해서 크롤링을 할 수 있다.
- 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 등의 특징들과 find 및 find_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()
'데이터 엔지니어링(DE) > 파이썬 활용' 카테고리의 다른 글
DataBase / ORM SQLalchemy / session (0) | 2021.07.24 |
---|---|
DOM( Document Object Model ) (0) | 2021.07.21 |
댓글