Today I Learned

웹크롤링을 위한 파이썬 사전지식 (UserAgent,for조건문,fstring)

by Holly Yoon

웹크롤링을 공부한 내용을 기록합니다. 강의는 해당 인프런 나도코딩 강의(무료)를 참고했습니다

1. UserAgent 

import requests
import re
from bs4 import BeautifulSoup

url = "https://www.coupang.com/np/categories/384561?eventCategory=breadcrumb&eventLabel=&page=1"
headers= {"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"}
res = requests.get(url, headers=headers)
res.raise_for_status()
soup = BeautifulSoup(res.text, "lxml")
  • 봇 접근을 막는 사이트의 경우 headers를 활용하여 UserAgent를 작성해주어야합니다.
  • 구글에 What is my UserAgent라고 검색시, 본인의 UserAgent 정보를 확인할 수 있습니다.

 

2. Get/Post 

쿠팡의 url을 자세히보면 url에 page=4와 같이 해당 상품의 pagination 정보가 들어간 것을 확인할 수 있습니다.

  • http 프로토콜은 http method를 포함한 요청을 서버에 보내고, 서버는 이에 알맞는 정보를 응답합니다.
  • 이 때, http method에는 get과 post방식이 대표적
  • get : url을 사용 (like 쿠팡) - ?뒤에 변수와 값을 포함
  • post : http메시지 body에 정보를 숨겨서 보냄 (usually 보안 데이터, 크기가 큰 데이터)

 

3. html 태그 

import requests
import re
from bs4 import BeautifulSoup

url = "https://www.coupang.com/np/categories/384561?eventCategory=breadcrumb&eventLabel=&page=1"
headers= {"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"}
res = requests.get(url, headers=headers)
res.raise_for_status()
soup = BeautifulSoup(res.text, "lxml") #lxml Parser를 통해 Soup객체로 만듬

items = soup.find_all("li", attrs={"class":re.compile("^search-product")}) #li태그 밑에 search-product로 class명이 시작하는 요소를 모두 찾아라 
print(items[0].find("div", attrs={"class":"name"}).get_text()) #items의 첫번째 요소(상품)의 div태그 class명이 name인 요소의 텍스트를 출력해라
  • 개발자모드로 접속하여 크롤링하고자 하는 데이터의 html 태그를 확인합니다.

 

4. 예외 처리

import requests
import re
from bs4 import BeautifulSoup

url = "https://www.coupang.com/np/categories/384561?eventCategory=breadcrumb&eventLabel=&page=1"
headers= {"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"}
res = requests.get(url, headers=headers)
res.raise_for_status()
soup = BeautifulSoup(res.text, "lxml")

items = soup.find_all("li", attrs={"class":re.compile("^search-product")})
for item in items:
    name = item.find("div", attrs={"class":"name"}).get_text()
    price = item.find("strong",attrs={"class":"price-value"}).get_text() 
    rate = item.find("em", attrs={"class":"price-value"})
    if rate :
        rate = rate.get_text()
    else:
        rate = "평점없음"
    rate_cnt = item.find("span", attrs={"class":"rating-total-count"})
    if rate_cnt :
        rate_cnt = rate_cnt.get_text()
    else:
        rate_cnt = "평점 수 없음"

    print(name, price, rate, rate_cnt)
  • 상품별로 <이름, 가격, 평점, 평점 수>를 크롤링하고자 합니다.  
  • 평점, 평점 수의 경우 없는 항목들이 존재함으로 if/else구문으로 예외처리를 진행합니다.

 

5. 여러 페이지에 걸쳐 크롤링

import requests
import re
from bs4 import BeautifulSoup

headers= {"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"}

#pagination
for i in range(1,6):
	print("페이지:",i)
    url = "https://www.coupang.com/np/categories/384561?eventCategory=breadcrumb&eventLabel=&page={}".format(i)
    res = requests.get(url, headers=headers)
    res.raise_for_status()
    soup = BeautifulSoup(res.text, "lxml")

    items = soup.find_all("li", attrs={"class":re.compile("^search-product")})
    for item in items:
        name = item.find("div", attrs={"class":"name"}).get_text()
        price = item.find("strong",attrs={"class":"price-value"}).get_text() 
        rate = item.find("em", attrs={"class":"price-value"})
        if rate :
            rate = rate.get_text()
        else:
            rate = "평점없음"
        rate_cnt = item.find("span", attrs={"class":"rating-total-count"})
        if rate_cnt :
            rate_cnt = rate_cnt.get_text()
        else:
            rate_cnt = "평점 수 없음"

        print(name, price, rate, rate_cnt)
  • for 조건문을 활용하여, 1~6페이지에 걸쳐 출력합니다.

 

6. f-string

import requests
import re
from bs4 import BeautifulSoup

headers= {"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"}

#pagination
for i in range(1,6):
	print("페이지:",i)
    url = "https://www.coupang.com/np/categories/384561?eventCategory=breadcrumb&eventLabel=&page={}".format(i)
    res = requests.get(url, headers=headers)
    res.raise_for_status()
    soup = BeautifulSoup(res.text, "lxml")

    items = soup.find_all("li", attrs={"class":re.compile("^search-product")})
    for item in items:
        name = item.find("div", attrs={"class":"name"}).get_text()
        price = item.find("strong",attrs={"class":"price-value"}).get_text() 
        rate = item.find("em", attrs={"class":"price-value"})
        if rate :
            rate = rate.get_text()
        else:
            rate = "평점없음"
        rate_cnt = item.find("span", attrs={"class":"rating-total-count"})
        if rate_cnt :
            rate_cnt = rate_cnt.get_text()
        else:
            rate_cnt = "평점 수 없음"

	#평점 4.5이상만 출력
    if float(rate)>=4.5 and int(rate_cnt)>=100:
    	print(f"제품명: {name}")
        print(f"가격: {price}")
        print(f"평점: {rate}점 ({rate_cnt}개)")
        print("-"*100) #줄긋기

 

 

블로그의 정보

Study Log by Holly

Holly Yoon

활동하기