본문 바로가기
AI 공부

크롤링 (HTML, CSS, User Agent, Selenium)

by AI Sonny 2022. 8. 22.
728x90

크롤링(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

 


오늘 크롤링 실습도 해보고 나름대로 재미있었다.

 

크롤링실습하는 것도 올리고 싶었는데 시간이 없어서 주말에 올려야할 것 같다.

 

오늘 하루도 너무 빡세게 수업을 들어 지친다..

728x90

'AI 공부' 카테고리의 다른 글

MLflow  (0) 2022.12.19
결측치 채우는 방법  (0) 2022.11.24

댓글