데이터 수집

Olivu·2024년 1월 8일
0

Data

목록 보기
1/5

Web Crawling(Web Scraping)

  • web 페이지를 자동으로 탐색하고, 데이터를 수집하는 프로세스
  • 파이썬에서 크롤링할 때 사용하는 라이브러리:
    1. Requests
    2. BeautifulSoup
    3. Selenium

Requests 라이브러리

  • HTTP 요청(Get, Post, Update, Delete 등)를 보내고 Response를 수신할 수 있는 라이브러리

라이브러리 설치

pip install requests

Get 메서드

  • 조회 기능
  • data를 url에 붙여 전송하기 때문에 보안에 취약함
  • headers, params, url을 정의. headers와 params는 딕셔너리 형태로 정의. 필수로 정의하지 않아도 된다.
## requests libraray import
import requests
        
## http request header 정의
headers = {
	'Content-Type' : 'text/html'
	}
        
## get parameter 정의 
params = {
      'where': 'nexearch',
      'sm' : 'top_hty',
      'fbm': '0',
      'ie' : 'utf8',
      'query' : 'python'
      }
        
## request를 보낼 url 선언
url = 'https://search.naver.com'+'/search.naver'
        
## request 보내기
resp = requests.get(url = url, headers = headers, params = params)

Post 메서드

  • 제출/변경
  • data를 http request body에 포함시켜 전송하여 보안에 상대적으로 안전함
  • headers, data, url를 정의
import requests
base_url = "https://fakerestapi.azurewebsites.net"
api_path = '/api/v1/Activities'
url = base_url + api_path
        
headers = {
	'Content-Type': 'application/json'
	}
        
data = {
	'id' : 0,
	'title': 'test-data',
	'dueDate' : '2023-11-15T05:38:00.704Z',
	'completed': 'true'
	}
        
	res = requests.post(url = url, data = data, headers = headers)

## JSON은 JavaScript Object Notation의 약자로, JavaScript에서 객체를 만들때 사용하는 표현식을 의미
## python의 json library는 json object를 handling하기 위한 library
        
import json
json.loads(res.text)

BeautifulSoup 라이브러리

  • requests로 가져온 HTML 코드를 파싱하여 데이터를 추출하는 라이브러리
  • 파싱(parsing)이란 문자열의 의미 분석이다.
  • 정적인 페이지를 가져올 때 사용한다.
  • Selenium 라이브러리보다 속도가 빠르다.

라이브러리 설치

pip install bs4

라이브러리 사용

import requests
url = 'http://naver.com'
resp = requests.get(url)
    
from bs4 import BeautifulSoup
soup = BeautifulSoup(resp.text, 'html.parser')
    
## soup의 내용을 정리된 형태로 출력
print(soup.prettify()) 
  • parent/child를 이용해 tree 구조를 찾아 쉽게 원하는 정보를 접근할 수 있다.
  • css selector를 이용해 쉽게 원하는 정보에 접근할 수 있다.
    • .class_name : class 속성값이 class_name으로 지정된 태그 선택

    • #id_name : id 속성값이 id_name으로 지정된 태그 선택

    • x > y : x 요소의 자식인 y 요소 태그 선택

    • x y : x 요소의 자손인 y 요소 태그 선택 ( x > y 보다 좀 더 포괄적인 개념)

      ## "book-item" 클래스의 자손인 "book-subject" 클래스 요소 선택
      soup.select(".book-item .book-subject")
      
      ## "book-item" 클래스의 자손인 "book-subject" 클래스의 요소에 대해 'get_text()' 메서드로 텍스트 내용만 추출하는 list comprehension
      [tag.get_text() for tag in soup.select(".book-item .book-subject")]

  • html 태그 이름을 이용한 soup parser 접근
    ## li 태그의 요소를 리스트 형태로 반환
    soup.select('li')
    
    ## a 태그의 요소를 리스트 형태로 반환
    soup.select('a')

  • 실습1: 네이버 뉴스에서 "삼성전자" 관련 기사 제목 찾아오기
    ## requests libraray import
    import requests
    
    ## http request header 정의
    headers = {
        'Content-Type' : 'text/html'
    }
    
    ## get parameter 정의. 
    params = {
        'where': 'm_news',
        'sm': 'mtb_jum',
        'query': '삼성전자'
        }
    
    ## request를 보낼 url 선언
    url = 'https://m.search.naver.com/search.naver'
    
    ## request 보내기
    resp = requests.get(url = url, headers = headers, params = params)
    
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(resp.text, 'html.parser')
    
    [tag.get_text() for tag in soup.select(".news_tit")]

  • 실습2: 나이키 신발 이름 크롤링
    import requests
    
    headers = {
        'Content-Type' : 'text/html'
    		}
    
    ## params 없음
    
    url = 'https://nike.com' + '/kr/w/women-shoes-5e1x6zy7ok'
    
    resp = requests.get(url = url, headers = headers)
    
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(resp.text, 'html.parser')
    
    [title.get_text() for title in soup.select(".product-card__title")]

Selenium 라이브러리

  • 웹 브라우저를 컨트롤하는 라이브러리
  • 동적인 페이지를 가져올 때 사용한다.
  • 글자 입력, 마우스 이동, 마우스 클릭 등 브라우저에서 가능한 모든 행동들을 제어할 수 있다.

Selenium 설치

pip3 install selenium webdriver_manager

Selenium 사용

1) Browser 오픈

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome(service = ChromeService(ChromeDriverManager().install()))

2) URL 접속

headers = {
        'User-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
    	}
        
## 원하는 URL 입력
url = "https://google.com"
    
driver.get(url)

3) Browser 제어하기

  • element xpath 정의
 	## 원하는 element의 xpath 정의
	elem_xpath ='/html/body/div[3]/div[1]/div/div[1]/div[1]/div/form/fieldset/div[1]/input'
    
    keyword_area = driver.find_element(By.XPATH, elem_xpath)

xpath는 element의 배치와 경로를 기술하기 위한 computer langauge다.
크롬 개발자 도구를 열어 내가 선택하고자 하는 element의 xpath를 확인한다.

  • element 클릭하기
keyword_area.click()

  • element에 text 입력하기
keyword = "원하는 키워드"
keyword_area.send_keys(keyword)

  • element에 enter key 입력하기
keyword_area.send_keys(Keys.ENTER)

  • browser 창 스크롤 내리기
import time

i = 0
while i < 1000:
    time.sleep(0.1)
    driver.find_element(By.TAG_NAME, value = 'body').send_keys(Keys.PAGE_DOWN)
    i +=1

  • browser html parsing
html_resp = driver.page_source

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_resp, 'html.parser')


실습: 구글에서 고양이 검색 후 이미지 다운로드

## import 라이브러리
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
    
    
## Chrome 드라이버를 시스템에 설치, 해당 드라이버를 사용하여 Selenium을 통해 Chrome 브라우저를 제어하기 위한 WebDriver 세션을 설정
driver = webdriver.Chrome(service = ChromeService(ChromeDriverManager().install()))
    
    
## url 접속
headers = {
    'User-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
    }
    
url = "https://google.com"
    
driver.get(url)
    
    
## 선택하고자 하는 element의 경로 정의
elem_xpath = "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/div/textarea"
keyword_area = driver.find_element(By.XPATH, elem_xpath)
    
    
## element 클릭
keyword_area.click()
    
    
## 검색어를 입력할 검색창 경로 정의
elem_xpath = '/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/div/textarea'
    
    
## 검색어 입력
keyword = "고양이"
keyword_area.send_keys(keyword)
    
    
## 검색 실행
keyword_area.send_keys(Keys.ENTER)
    
    
## 이미지 탭 경로 정의 & 클릭
elem_xpath = "/html/body/div[6]/div/div[3]/div/div[1]/div/div[1]/div/div[2]/a"
keyword_area = driver.find_element(By.XPATH, elem_xpath)
keyword_area.click()
    
    
## webdriver의 현재 페이지 소스 코드를 가져오기
html_resp = driver.page_source

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_resp, 'html.parser')
    
    
## "FRuiCf.islib.nfEiy" 클래스의 img 태그 요소 선택
a = soup.select(".FRuiCf.islib.nfEiy img")
    
    
## img 태그에서 'src' 속성값만 추출하여 리스트로 저장
img_url = [img.get('src') for img in a]
    
    
## 데이터를 다운로드 및 열기 위한 라이브러리 import
import urllib.request
    
    
## img_url의 길이만큼 반복문 실행
for i in range(len(img_url)):
	## img_url 값이 None이 아닌 경우 지정한 경로에 다운로드 진행
    if img_url[i] is not None: 
          file_path = f"D:\\cats\\test{i}.png"  # 로컬 경로에 맞게 수정
          urllib.request.urlretrieve(img_url[i], file_path)
          print(f"이미지 {i + 1} 다운로드 성공")
    else:
          print(f"Image {i + 1} 스킵: URL이 None입니다")
profile
천천히 꾸준히 기록

0개의 댓글