코뮤니티 모각코

[Python] 정적 크롤링 (2)

넝구리 2022. 4. 13. 15:57

'코뮤니티 모각코' 활동에서의 학습 내용을 바탕으로 작성한 글입니다.

자세한 내용은 링크를 통해 확인하시기 바랍니다.


정적 크롤링 3

 

https://codemate.kr/@datasponge/정적-크롤링-3

 

정적 크롤링 3 by datasponge | 코드메이트

크롤링 대상 사이트 살펴보기 ex) G마켓 ① 사이트 접속 ② 상품 검색 ③ 검색어의 URL 패턴 확인 -> '마스크'와 '코로나'가 , URL 주소에 포함되어 있음 -> 'keyword=' 라는 문구 뒤에 추가되는 문자열이

codemate.kr

 

 

크롤링 대상 사이트 살펴보기

 

ex) G마켓

 

사이트 접속

 

 

상품 검색

 

 

검색어의 URL 패턴 확인

 

-> '마스크'와 '코로나'가 , URL 주소에 포함되어 있음

-> 'keyword=' 라는 문구 뒤에 추가되는 문자열이 검색어가 되는 구조임을 알 수 있음

 

 

상품의 태그 및 선택자 확인

 

모든 데이터를 감싸는 틀

 

-> 상품만 감싸는 틀을 찾기 어려운 경우, 직접 HTML 구조를 거슬러 가면서 틀을 찾아야 함

-> 틀에 속하는 상품을 선택하고, 개발자 도구에서 위로 올라가면서 탐색

 

-> 선택된 태그가 모든 상품을 포함하고 있는 태그임

-> 이 경우 HTML의 다른 요소들도 동일한 클래스를 갖기 때문에 class만 선택자로 사용해서는 안됨

-> 우리가 원하는 틀만 가져오기 위해 module-design-id와 class 둘 다 사용해야 함

-> 우리가 필요한 태그 : <div class="section__module-wrap" module-design-id="15">

 

각 상품의 태그

 

-> 각 상품을 의미하는 태그 : <div class="box__item-container">

 

각 상품의 제목과 가격

 

-> 제목 : <span class="text__item">

-> 가격 : <strong class="text text__value">

 

데이터 추출 방식

✔ find를 사용해 데이터를 감싸는 큰 틀을 먼저 추출할 수도 있고, find_all을 사용해 바로 각 데이터를 추출할 수도 있음

✔ 웹사이트마다, 사람마다 데이터 추출 방식이 다름

✔ 큰 틀을 찾아 데이터의 범위를 제한하면 틀 밖에서 각 상품과 같은 클래스를 사용하는 데이터가 추출되는 것을 방지할 수 있음

✔ 큰 틀을 먼저 찾아내는 방식은 콘솔에서 같은 클래스가 존재하는지 검사하지 않아도 되기 때문에 효율적임

 

 

 

정적 크롤링 4

 

https://codemate.kr/@datasponge/정적-크롤링-4

 

정적 크롤링 4 by datasponge | 코드메이트

파이썬 코드 작성 ex) G마켓 사이트에서 상품 정보 가져오기 ✔ 기본 크롤링 ① 라이브러리 불러오기 import requests import bs4 ② URL 주소 입력 및 HTML 받아오기 import requests import bs4 URL = "ht

codemate.kr

 

 

파이썬 코드 작성

 

ex) G마켓 사이트에서 상품 정보 가져오기

 

기본 크롤링

 

라이브러리 불러오기

import requests
import bs4

 

URL 주소 입력 및 HTML 받아오기

import requests
import bs4

URL = "https://browse.gmarket.co.kr/search?keyword=마스크"
raw = requests.get(URL)

 

BeautifulSoup 클래스 객체 생성

import requests
import bs4

URL = "https://browse.gmarket.co.kr/search?keyword=마스크"
raw = requests.get(URL)

html = bs4.BeautifulSoup(raw.text, 'html.parser')

 

데이터를 감싸는 큰 틀 추출

import requests
import bs4

URL = "https://browse.gmarket.co.kr/search?keyword=마스크"
raw = requests.get(URL)

html = bs4.BeautifulSoup(raw.text, 'html.parser')

box = html.find('div', {'class' : 'section__module-wrap', 'module-design-id' : '15'})

 

각 상품 추출

import requests
import bs4

URL = "https://browse.gmarket.co.kr/search?keyword=마스크"
raw = requests.get(URL)

html = bs4.BeautifulSoup(raw.text, 'html.parser')

box = html.find('div', {'class' : 'section__module-wrap', 'module-design-id' : '15'})

items = box.find_all('div', {"class" : 'box__item-container'})

 

각 상품의 이름과 가격 추출

import requests
import bs4

URL = "https://browse.gmarket.co.kr/search?keyword=마스크"
raw = requests.get(URL)

html = bs4.BeautifulSoup(raw.text, 'html.parser')

box = html.find('div', {'class' : 'section__module-wrap', 'module-design-id' : '15'})

items = box.find_all('div', {"class" : 'box__item-container'})

for item in items:
	title = item.find('span', {'class' : 'text__item'})
	price = item.find('strong', {'class' : 'text__value'})

 

문자열 추출 및 출력

import requests
import bs4

URL = "https://browse.gmarket.co.kr/search?keyword=마스크"
raw = requests.get(URL)

html = bs4.BeautifulSoup(raw.text, 'html.parser')

box = html.find('div', {'class' : 'section__module-wrap', 'module-design-id' : '15'})

items = box.find_all('div', {"class" : 'box__item-container'})

print("< G마켓의 마스크 상품 정보 >")
for item in items[:10]:     # 10개의 상품만 출력
	title = item.find('span', {'class' : 'text__item'})
	price = item.find('strong', {'class' : 'text__value'})
	print("이름 : ", title.text)
	print('가격 : ', price.text)
	print()

> 실행결과

 

✔ 크롤링 기능 추가 : 입력한 키워드의 상품 정보 받아오기

 

입력 구문과 반복문 추가

import requests
import bs4

# 입력 구문과 반복문 추가
while True:
	keyword = input("검색을 원하는 키워드를 입력하세요. ( 0을 입력하면 종료 )")
	if keyword == "0":
		break

# 기존 코드
	URL = "https://browse.gmarket.co.kr/search?keyword=마스크"
	raw = requests.get(URL)

	html = bs4.BeautifulSoup(raw.text, 'html.parser')

	box = html.find('div', {'class' : 'section__module-wrap', 'module-design-id' : '15'})

	items = box.find_all('div', {"class" : 'box__item-container'})

	print("< G마켓의 마스크 상품 정보 >")
	for item in items[:10]:
		title = item.find('span', {'class' : 'text__item'})
		price = item.find('strong', {'class' : 'text__value'})
		print("이름 : ", title.text)
		print('가격 : ', price.text)
		print()

 

URL 수정

import requests
import bs4

while True:
	keyword = input("검색을 원하는 키워드를 입력하세요. ( 0을 입력하면 종료 )")
	if keyword == "0":
		break

# URL 수정
	URL = "https://browse.gmarket.co.kr/search?keyword=" + keyword
	raw = requests.get(URL)

	html = bs4.BeautifulSoup(raw.text, 'html.parser')

	box = html.find('div', {'class' : 'section__module-wrap', 'module-design-id' : '15'})

	items = box.find_all('div', {"class" : 'box__item-container'})

	print("< G마켓의 마스크 상품 정보 >")
	for item in items[:10]:
		title = item.find('span', {'class' : 'text__item'})
		price = item.find('strong', {'class' : 'text__value'})
		print("이름 : ", title.text)
		print('가격 : ', price.text)
		print()

 

출력 구문 수정

import requests
import bs4

while True:
	keyword = input("검색을 원하는 키워드를 입력하세요. ( 0을 입력하면 종료 )")
	if keyword == "0":
		break

	URL = "https://browse.gmarket.co.kr/search?keyword=" + keyword
	raw = requests.get(URL)

	html = bs4.BeautifulSoup(raw.text, 'html.parser')

	box = html.find('div', {'class' : 'section__module-wrap', 'module-design-id' : '15'})

	items = box.find_all('div', {"class" : 'box__item-container'})

# 출력 구문 수정
	print("< G마켓의", keyword, "상품 정보 >")
	for item in items[:3]:     # 3개의 상품만 출력
		title = item.find('span', {'class' : 'text__item'})
		price = item.find('strong', {'class' : 'text__value'})
		print("이름 : ", title.text)
		print('가격 : ', price.text)
		print()

> 실행결과

 

ex) 검색어 관련 뉴스 기사 제목 100개 가져오기

 

코드

import requests
from bs4 import BeautifulSoup

keyword = input("뉴스 검색 키워드: ")
count = 0

for page in range(1, 11):
	news_url = 'https://search.hankyung.com/apps.frm/search.news?query=' + keyword + '&page=' + str(page)
	raw = requests.get(news_url)

	soup = BeautifulSoup(raw.text, 'html.parser')

	box = soup.find('ul', {'class' : 'article'})
	all_title = box.find_all('em', {'class': 'tit'})

	for title in all_title:
		count += 1
		t = title.text
		print(count, '-', t.strip())