AI 부트캠프 | Week 3-2) (#웹크롤링)

Gomcha ·2023년 8월 5일
0

FC AI 6기 부트캠프

목록 보기
5/13
post-thumbnail

0. 목차

  1. 웹과 네트워크 요청
  2. Request 모듈
  3. HTML과 웹 스크래핑

1. 웹과 네트워크 요청

01. 웹에 대한 이해

01-1) 크롤링

  • 웹 페이지로부터 데이터를 추출하는 행위
  • 구글크롬에서 개발자 모드로 진입하여, HTML문서 확인 가능
    - 윈도우 : F12
    - 맥 : Command + Option + I

01-2) 요청과 응답

  • 요청 : 브라우저(내 컴퓨터)가 특정한 정보(입력한 정보 e.g. 사이트주소)를 달라고 하는 것
  • 응답 : 내 컴퓨터로 HTML 문서를 응답으로서 보내는 것

02. 네트워크 요청 방식

02-1) Get 요청

  • 웹 서버가 자체적으로 가진 정보를 달라고 하는 것 (웹 서버 측에 변화X)
    - 요청하는 것에 있어 별도 request data 불필요

02-2) Post 요청

  • 내 컴퓨터가 제출한 정보가 웹 서버에 반영되는 방식의 요청 (웹 서버 측에 변화O)
    - 요청하는 것에 있어 request data 필요

2. Request 모듈

01. Request모듈 사용

01-1) 모듈 설치

  • 기능 : 특정한 서버에 네트워크 요청을 보내고, 헤당 서버가 가지고 있는 정보나 데이터(응답)를 받아오는 기능
pip install requests # 모듈 설치
import requests # 불러오기

01-2) 요청 보내기

  • Get 요청
    : 네이버 주소로 요청을 보내고 받은응답(HTML문서)을 response라는 변수에 저장
response = requests.get('https://www.naver.com')
  • 출력
print(response.text) # .text 를 붙이면 데이터 부분 출력
  • Post 요청
requests.post(주소, 요청 데이터)

02. Request 연습

02-1) 브라우저 접근

  • 이름:값 형태의 정보가 이어진 딕셔너리 형태로 구성

02-2) Get

  • Get요청(post 가져오기) → 글 목록을 응답 데이터로 보내줌
import requests

response = requests.get('https://jsonplaceholder.typicode.com/posts')
print(response.text)
  • 하나만 가져오는 기능도 있음
import requests

response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
print(response.text)
  • title만 출력하고 싶다면?
import requests
import json

response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
json_response = json.loads(response.text)
print(json_response['title'])

02-3) Post

  • Post요청 → 글 데이터를 만들어서, 그 데이터를 웹 서버에 등록
    : requests.post(주소, 요청 데이터)
  • 중요사항 : 일반적으로 크롤링 할 때 정보가 따로 저장되어 있지 않음. ⇒ 웹 브라우저를 사용하면서, 직접 해당 주소가 어떤 요청을 허용하는지, 어떤 데이터를 필요로 하는지 분석 및 추리 필요
import requests

my_post = {'title': '제목', 'body': '내용'}
response = requests.post('https://jsonplaceholder.typicode.com/posts', my_post)
print(response.text)

3. HTML과 웹 스크래핑

01. HTML문서 소스 코드

01-1) HTML문서 형태

  • 많은 꺽쇠(<>)들의 조합⇒ 여러 개의 중첩된태그으로 구성되어 있음
<div class="direct_area">
<a href="http://news.naver.com/" class="link_news" data-clk="newshome">네이버뉴스</a>
<a href="http://entertain.naver.com/home" class="link_direct" data-clk="entertainment">연예</a>
<a href="http://sports.news.naver.com/" class="link_direct" data-clk="sports">스포츠</a>
</div>

01-2) 태그의 종류

  • div : 영역을 구분하는 태그(뉴스 영역, 로그인 영역 등을 구분)
  • a : 하이퍼링크 태그(다른 주소로 연결하는 부분)
  • p : 문단 태그(특정한 문서에서 문단 부분)
  • h1~h6 : 제목 태그(특정한 문서에서 제목 부분)

02. 선택자(Selector)

02-1) 선택자

  • HTML문서의 특정 부분에 이름을 붙인 것 ⇒ 우리는 그 이름을 가지고 HTML 문서 내의 특정 부분(우리가 필요한 데이터)를 찾을 수 있음
  • 기능 : HTML 문서 내의 어떤 특정 태그에 이름을 지어줌
  • id와 class라는 선택자 등이 존재
    - 가격 정보를 추출하고 싶을 때 : price라는 class이름 부분 가져오기
    - 라운드티 정보 추출 : clothes라는 id 이름을 가진 부분 가져오기
<html> 
    <head> 
    </head> 
    <body> 
        <h1> 장바구니
            <p id='clothes' class='name' title='라운드티'> 라운드티
                <span class = 'number'> 25 </span> 
                <span class = 'price'> 29000 </span> 
                <span class = 'menu'> 의류</span> 
                <a href = 'http://www.naver.com'> 바로가기 </a> 
            </p> 
            <p id='watch' class='name' title='시계'> 시계
                <span class = 'number'> 28 </span>
                <span class = 'price'> 32000 </span> 
                <span class = 'menu'> 액세서리 </span> 
                <a href = 'http://www.facebook.com'> 바로가기 </a> 
            </p> 
        </h1> 
    </body> 
</html>

03. BeautifulSoup

  • HTML 문서(그냥 문자열)를 파이썬 데이터 구조(리스트 및 딕셔너리) 형태로 정리 ⇒ 파싱이라고 함

03-1) 모듈 설치 및 함수 가져오기

pip install beautifulSoup4

# bs4라는 패키지로부터 BeautifulSoup라는 모듈을 임포트
from bs4 import BeautifulSoup

03-2) 필요 부분 추출

1) HTML 문서를 문자열로 저장

# HTML 문서를 문자열 html로 저장
html = '''
<html> 
    <head> 
    </head> 
    <body> 
        <h1> 장바구니
            <p id='clothes' class='name' title='라운드티'> 라운드티
                <span class = 'number'> 25 </span> 
                <span class = 'price'> 29000 </span> 
                <span class = 'menu'> 의류</span> 
                <a href = 'http://www.naver.com'> 바로가기 </a> 
            </p> 
            <p id='watch' class='name' title='시계'> 시계
                <span class = 'number'> 28 </span>
                <span class = 'price'> 32000 </span> 
                <span class = 'menu'> 액세서리 </span> 
                <a href = 'http://www.facebook.com'> 바로가기 </a> 
            </p> 
        </h1> 
    </body> 
</html>
'''

2) BeautifulSoup 함수에 인자로 명시해서 파싱
⇒ 파싱한 데이터는 BeautifulSoup 인스턴스(객체)라고 함
⇒ HTML 문서에서 선택자를 기준으로 원하는 정보 찾기O
⇒ soup.select('찾는정보)

# BeautifulSoup 인스턴스 생성. 두번째 매개변수는 분석할 분석기(parser)의 종류.
soup = BeautifulSoup(html, 'html.parser')

# select 선택자를 사용하여 필요한 정보 찾기
soup.select('찾는정보')
  • soup.select('태그명') : 태그를 입력으로 사용할 경우
  • soup.select('.클래스명') : 클래스를 입력으로 사용할 경우 (. 은 클래스를 뜻하는 특수기호)
  • soup.select('#아이디') : ID를 입력으로 사용할 경우 (# 은 id를 뜻하는 특수기호)
  • soup.select('상위태그명 하위태그명') : 자손 관계 (어떤 태그 내부에 있는 모든 태그를 자손이라고 함)
  • soup.select('상위태그명 > 하위태그명') : 자식 관계 (어떤 태그 내부에 있는 태그 중 바로 한 단계 아래에 있는 태그를 자식이라고 함)

03-3) soup.태그명

  • 해당 태그를 포함하여 태그 끝까지 문장 추출. 단, 해당 태그가 여러 개 있으면 첫번째 태그만 가져옴

03-3) soup.태그명.get('속성명')

  • 해당 속성의 값을 가져옴

4. Selenium 크롤링

01. Selenium의 필요성

01-1) Selenium 크롤링을 하는 이유

  • 클릭과 상호작용이 이루어지기 전까지는, 원하는 정보를 가져올 수 없음
    ⇒ Selenium을 이용해 직접 상호작용을 한 후에 바뀐 HTML을 크롤링하는 방법

02. 설치

02-1) 구글크롬 설치

02-2) Selenium 설치

# selenium 설치
pip install selenium

import time
from selenium import webdriver

# 크롬 드라이버 실행 파일이 어디있는지 위치 명시
# 지금은 같은 경로에 있기 때문에, () 안에 아무것도 명시하지 않아도 무방
driver = webdriver.Chrome()
# 어떤 주소로 크롬 브라우저가 접속할 건지 지정
driver.get('https://naver.com')
# 브라우저 종료 전에 5초 동안 잠시 대기
time.sleep(5)
# 브라우저 종료
driver.quit()

03. 사용법

03-1) 크롤링 방법

  1. 상호작용 (클릭, 입력) 이 필요한 곳의 태그, 선택자를 찾고
  2. 해당 HTML 요소에 대해서 단어 입력 혹은 클릭 등의 상호작용을 하고
  3. 상호작용에 따른 로딩이 모두 이루어진 후에, HTML 요소를 다 가져온다.

03-2) 사용 함수

  • 요소 하나 찾기 - driver.find_element(By.CSS_SELECTOR, '태그, 선택자')
  • 요소 여러개 찾기 - driver.find_elements(By.CSS_SELECTOR, '태그, 선택자')
  • 글자 입력하기 - 요소.send_keys(’단어’)
  • 요소 클릭하기 - 요소.click()
  • 특정한 요소가 로딩될 때까지 기다리기 - WebDriverWait(driver, 초).until(EC.presence_of_element_located((By.CSS_SELECTOR, ‘태그, 선택자’)))
  • 그냥 기다리기 - time.sleep(초)
  • 현재 페이지의 HTML 다 가져오기 - driver.page_source
profile
공부하는 데이터 분석가 👩‍💻

0개의 댓글