크롤링(Crawling)
- 자동으로 웹페이지의 정보를 수집하는 것
- 스크래핑(scraping)이란?
크롤링을 통한 수집한 정보를 분석해서 필요한 정보만 추출하는 일
HTML(Hyper Text Markup Language)
- 웹페이지에 필요한 구성요소를 구성하는 Markup 언어
- 태그를 이용해 화면의 레이아웃 구조와 텍스트, 요소 등을 표현한다.
HTML의 구조
<!DOCTYPE HTML>
<html>
<head>
<title>웹문서의 제목</title>
</head>
<body>
<div>
<a></a>
<p></p>
</div>
웹문서의 내용(실제 브라우저에 표시되는 내용)
</body>
</html>
CSS
- HTMl의 요소를 꾸며주는 스타일 시트
- CSS 선택자를 이용해서 HTML 요소에 접근하여 꾸며준다.
CSS 선택자
- 태그명으로 접근하는 예시
- a 태그 접근: a
- 태그의 class 속성명으로 접근하는 예시
- class="btn" : .btn
- 태그의 id 속성명으로 접근하는 예시
- id="btn" : #btn
예시
html = """
<!DOCYTYPE HTML>
<html>
<head>
<title>HTML 페이지</title>
</head>
<style>
#naver-link{color:red;}
.p-el{font-size:30px;}
button{color:blue;}
</style>
<body>
<div>
<a id="naver-link" href="https://www.naver.com" target="_blank">네이버로 이동하기</a>
<p class="p-el">안녕하세요 html 페이지 입니다.</p>
<p class="p-el">반갑습니다.</p>
<p>잘가요.</p>
<button class="btn">클릭하기1</button>
<button>클릭하기2</button>
</div>
<div id="div-tag">
<p class="p1 p-tag">첫번째 p태그</p>
<p class="p2 p-tag">두번째 p태그</p>
<p class="p3 p-tag">세번째 p태그</p>
</div>
</body>
</html>
"""
BeautifulSoup로 파싱
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'html.parser')
soup
=> <!--DOCYTYPE HTML-->
<html>
<head>
<title>HTML 페이지</title>
</head>
<style>
#naver-link{color:red;}
.p-el{font-size:30px;}
button{color:blue;}
</style>
<body>
<div>
<a href="https://www.naver.com" id="naver-link" target="_blank">네이버로 이동하기</a>
<p class="p-el">안녕하세요 html 페이지 입니다.</p>
<p class="p-el">반갑습니다.</p>
<p>잘가요.</p>
<button class="btn">클릭하기1</button>
<button>클릭하기2</button>
</div>
<div id="div-tag">
<p class="p1 p-tag">첫번째 p태그</p>
<p class="p2 p-tag">두번째 p태그</p>
<p class="p3 p-tag">세번째 p태그</p>
</div>
</body>
</html>
결과
type(soup)
=> bs4.BeautifulSoup
태그명과 속성명&속성값을 이용해서 접근하기
find("태그명",{"속성명 : "속성값"})
- 한개의 요소만 찾는다.
예시
el = soup.find("p")
el
=> <p class="p-el">안녕하세요 html 페이지 입니다.</p>
→ p-el이 있는 첫부분을 찾아낸다.
find_all("div",{"속성명":"속성값"})
- 여러개 찾기
- 리스트를 반환한다.
예시
el = soup.find("div",{"id":"div-tag"}) # id 속성값이 중복되면 안된다.
el
=> <div id="div-tag">
<p class="p1 p-tag">첫번째 p태그</p>
<p class="p2 p-tag">두번째 p태그</p>
<p class="p3 p-tag">세번째 p태그</p>
</div>
→ div의 id가 div-tag인 것을 찾아낸다.
CSS 선택자(selector)를 사용해서 추출
- 태그명을 이용한 선택
el = soup.select_one("a")
type(el)
=> bs4.element.Tag
- id 속성을 이용한 선택
soup.select_one("#naver-link")
=> <a href="https://www.naver.com" id="naver-link" target="_blank">네이버로 이동하기</a>
- class 속성을 이용한 선택
soup.select_one(".p-el")
=> <p class="p-el">안녕하세요 html 페이지 입니다.</p>
- 클래스는 속성값을 여러개 넣을 수 있다.
<div class="div-1 div-2 div-3"></div>
- 다음의 예시는 한칸을 띄울 경우 body 태그 하위에 모든 p태그를 가져오겠다는 의미
soup.select("body p")
=> [<p class="p-el">안녕하세요 html 페이지 입니다.</p>,
<p class="p-el">반갑습니다.</p>,
<p>잘가요.</p>,
<p class="p1 p-tag">첫번째 p태그</p>,
<p class="p2 p-tag">두번째 p태그</p>,
<p class="p3 p-tag">세번째 p태그</p>]
- 다음의 예시에서 > 화살괄호의 의미는 body태그에 바로 하위에 p 태그들만 가져오겠다라는 의미
soup.select("#div-tag > p")
=> [<p class="p1 p-tag">첫번째 p태그</p>,
<p class="p2 p-tag">두번째 p태그</p>,
<p class="p3 p-tag">세번째 p태그</p>]
- button 태그이면서 클래스명이 btn인 것을 찾고 싶다.
soup.select("button.btn")
=> [<button class="btn">클릭하기1</button>]
- a 태그이면서 id명이 naver-link인 것을 찾고싶다.
soup.select("a#naver-link") # # = id 선택하는 것
=> [<a href="https://www.naver.com" id="naver-link" target="_blank">네이버로 이동하기</a>]
인코딩 에러 예시
text와 content의 메소드를 사용하면 url의 정보를 가져올 수 있다.
그러나 content는 인코딩이 자동으로 되고, text는 인코딩이 안된다는 차이가 있다.
항상 content를 사용하는 습관을 기르자!
xpath(XML Path Language)
- XML 이나 HTML 의 특정 요소를 선택할 때 사용
- xpath의 구성요소
- //로 시작해야함(최상위 요소라는 의미)
- // 중간에 있을 경우는 하위에 모든 요소를 찾겠다라는 의미 (css의 공백과 비슷)
- / 바로 하위 요소를 찾겠다라는 의미 (css의 >와 비슷)
- * 모든 태그라는 의미
- [@id = "아이디 이름"]
- id 속성의 값이 아이디 이름인 요소를 찾겠다. (#와 비슷)
- div[3]
- 같은 레벨의 div태그 중에서 3번째 요소를 선택
- 1부터 시작
예시
root.xpath("//*[@id='naver-link']")[0].attrib # css -> #naver-link
=> {'id': 'naver-link', 'href': 'https://www.naver.com', 'target': '_blank'}
대체적으로 위와 같은 코드를 보면 xpath가 더 편리해보인다.
사용하는 사람에 따라 장단점이 있지만 나는 xpath를 쓰는 것이 더 이해가 잘가는 것 같다.
User Agent
- 브라우저 종류에 대한 정보
- 요청 시 header 영역에 담긴다.
즉, 웹페이지에 접속할 때 플랫폼에 맞는 페이지로 연결하기 위한 정보를 사용자 에이전트라한다.
!pip install fake_useragent
from fake_useragent import UserAgent
ua = UserAgent(use_cache_server = True)
headers = {"user-agent" : ua.random}
res = requests.get("https://onoffmix.com/",headers=headers)
res.text
=> 결과가 너무길다... 아무튼 출력이 된다..
Selenium
- 브라우저를 직접 실행하여 자동화하고, 브라우저 상에 있는 데이터를 수집
- 웹테스트 자동화에 쓰임
- 홈페이지의 모든 걸 받는다. (java script,css,html 등)'
Selenium은 3.X버전까지만하더라도 수동으로 드라이버를 다운하고, 경로를 지정해야했다.
그러나 4.X 부터는 WebDriverManager가 자동으로 Web브라우저의 버전에 맞게 다운로드하고 실행한다.
pip install beautifulsoup4
pip install webdriver-manager
pip install selenium
오늘 크롤링 실습도 해보고 나름대로 재미있었다.
크롤링실습하는 것도 올리고 싶었는데 시간이 없어서 주말에 올려야할 것 같다.
오늘 하루도 너무 빡세게 수업을 들어 지친다..
'AI 공부' 카테고리의 다른 글
MLflow (0) | 2022.12.19 |
---|---|
결측치 채우는 방법 (0) | 2022.11.24 |
댓글