웹사이트 검색

Beautiful Soup을 사용하여 Amazon 제품 정보를 긁는 방법


웹 스크래핑은 웹사이트에서 관련 정보를 추출하고 추가 사용을 위해 로컬 시스템에 저장하는 프로그래밍 기반 기술입니다.

현대에 웹 스크래핑은 데이터 과학 및 마케팅 분야에서 많은 응용 프로그램을 가지고 있습니다. 전 세계의 웹 스크레이퍼는 개인적 또는 전문적 사용을 위해 수많은 정보를 수집합니다. 더욱이 오늘날 거대 기술 기업들은 소비자 기반의 요구를 충족시키기 위해 이러한 웹 스크래핑 방법에 의존하고 있습니다.

이 기사에서는 Amazon 웹 사이트에서 제품 정보를 스크랩합니다. 따라서 "Playstation 4\를 대상 제품으로 간주합니다.

참고: 웹 사이트 레이아웃과 태그는 시간이 지남에 따라 변경될 수 있습니다. 따라서 자체 구현이 문제가 되지 않도록 독자는 스크래핑의 개념을 이해하는 것이 좋습니다.

웹 스크래핑 서비스

웹 스크래핑을 이용하여 서비스를 구축하려면 프록시 관리는 물론 IP 차단까지 거쳐야 할 수도 있습니다. 기본 기술과 프로세스를 아는 것도 좋지만 대량 스크래핑의 경우 주거용 대리 서비스와 같은 스크래핑 API 제공 업체와 협력하는 것이 좋습니다.

몇 가지 기본 요구 사항:

수프를 만들기 위해서는 적절한 재료가 필요합니다. 마찬가지로 새로운 웹 스크레이퍼에는 특정 구성 요소가 필요합니다.

  • Python - 사용하기 쉽고 방대한 라이브러리 모음으로 인해 Python은 웹사이트 스크래핑을 위한 숫자가 되었습니다. 그러나 사용자가 사전 설치하지 않은 경우 여기를 참조하십시오.
  • 아름다운 수프 - 많은 Python용 웹 스크래핑 라이브러리 중 하나입니다. 라이브러리를 쉽고 깔끔하게 사용하면 웹 스크래핑의 최고 경쟁자가 됩니다. Python을 성공적으로 설치한 후 사용자는 다음과 같이 Beautiful Soup을 설치할 수 있습니다.

pip install bs4

  • HTML 태그의 기본 이해 - HTML 태그에 대한 필수 정보를 얻으려면 이 자습서를 참조하십시오.
  • 웹 브라우저 - 웹사이트에서 많은 불필요한 정보를 버려야 하므로 필터링을 위해 특정 ID와 태그가 필요합니다. 따라서 Google Chrome 또는 Mozilla Firefox와 같은 웹 브라우저는 이러한 태그를 검색하는 역할을 합니다.

사용자 에이전트 만들기

많은 웹사이트에는 로봇이 데이터에 액세스하지 못하도록 차단하는 특정 프로토콜이 있습니다. 따라서 스크립트에서 데이터를 추출하기 위해서는 User-Agent를 생성해야 합니다. User-Agent는 기본적으로 요청을 보내는 호스트 유형에 대해 서버에 알려주는 문자열입니다.

이 웹사이트에는 독자가 선택할 수 있는 수많은 사용자 에이전트가 포함되어 있습니다. 다음은 헤더 값 내의 User-Agent의 예입니다.

HEADERS = ({'User-Agent':
            'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36',
            'Accept-Language': 'en-US, en;q=0.5'})

HEADERS에는 "Accept-Language\라는 추가 필드가 있으며, 필요한 경우 웹페이지를 미국 영어로 번역합니다.

URL로 요청 보내기

URL(Uniform Resource Locator)로 웹 페이지에 액세스합니다. URL의 도움으로 데이터에 액세스하기 위해 웹 페이지에 요청을 보냅니다.

URL = "https://www.amazon.com/Sony-PlayStation-Pro-1TB-Console-4/dp/B07K14XKZH/"
webpage = requests.get(URL, headers=HEADERS)

요청한 웹페이지에 Amazon 제품이 있습니다. 따라서 Python 스크립트는 "제품 이름\, "현재 가격\ 등과 같은 제품 세부 정보를 추출하는 데 중점을 둡니다.

참고: URL에 대한 요청은 \requests\ 라이브러리를 통해 전송됩니다. 사용자에게 "No module named requests\ 오류가 표시되는 경우 \pip install requests\로 설치할 수 있습니다.

정보 수프 만들기

webpage 변수는 웹사이트에서 받은 응답을 포함합니다. 응답 내용과 파서 유형을 Beautiful Soup 함수에 전달합니다.

soup = BeautifulSoup(webpage.content, "lxml")

lxml은 HTML 페이지를 복잡한 파이썬 객체로 분해하기 위해 Beautiful Soup에서 사용하는 고속 파서입니다. 일반적으로 다음과 같은 네 가지 종류의 Python 객체가 있습니다.

  • 태그 - 이름과 속성을 포함하는 HTML 또는 XML 태그에 해당합니다.
  • NavigableString - 태그 내에 저장된 텍스트에 해당합니다.
  • BeautifulSoup - 사실 전체 파싱된 문서입니다.
  • 설명 - 마지막으로 위의 세 가지 범주에 포함되지 않은 HTML 페이지의 나머지 부분입니다.

객체 추출을 위한 정확한 태그 찾기

이 프로젝트에서 가장 바쁜 부분 중 하나는 관련 정보를 저장하는 ID와 태그를 발굴하는 것입니다. 앞에서 언급했듯이 이 작업을 수행하기 위해 웹 브라우저를 사용합니다.

브라우저에서 웹 페이지를 열고 마우스 오른쪽 버튼을 눌러 관련 요소를 검사합니다.

결과적으로 다음 그림과 같이 화면 오른쪽에 패널이 열립니다.

태그 값을 얻으면 정보 추출이 식은 죽 먹기가 됩니다. 그러나 Beautiful Soup Object에 정의된 특정 기능을 학습해야 합니다.

제품 제목 추출

특정 속성이 있는 특정 태그를 검색하는 데 사용할 수 있는 find() 함수를 사용하여 제품 제목이 포함된 태그 개체를 찾습니다.

# Outer Tag Object
title = soup.find("span", attrs={"id":'productTitle'})

그런 다음 NavigableString 객체를 꺼냅니다.

# Inner NavigableString Object
title_value = title.string

마지막으로 여분의 공백을 제거하고 개체를 문자열 값으로 변환합니다.

# Title as a string value
title_string = title_value.strip()

type() 함수를 사용하여 각 변수의 유형을 살펴볼 수 있습니다.

# Printing types of values for efficient understanding
print(type(title))
print(type(title_value))
print(type(title_string))
print()

# Printing Product Title
print("Product Title = ", title_string)

산출:

<class 'bs4.element.Tag'>
<class 'bs4.element.NavigableString'>
<class 'str'>

Product Title =  Sony PlayStation 4 Pro 1TB Console - Black (PS4 Pro)

같은 방식으로 "Price of the Product\ 및 "Consumer Ratings\와 같은 다른 제품 세부 정보에 대한 태그 값을 파악해야 합니다.

제품 정보 추출을 위한 Python 스크립트

다음 Python 스크립트는 제품에 대한 다음 세부 정보를 표시합니다.

  • 제품 제목
  • 제품 가격
  • 제품 등급
  • 고객 리뷰 수
  • 제품 가용성

from bs4 import BeautifulSoup
import requests

# Function to extract Product Title
def get_title(soup):
	
	try:
		# Outer Tag Object
		title = soup.find("span", attrs={"id":'productTitle'})

		# Inner NavigableString Object
		title_value = title.string

		# Title as a string value
		title_string = title_value.strip()

		# # Printing types of values for efficient understanding
		# print(type(title))
		# print(type(title_value))
		# print(type(title_string))
		# print()

	except AttributeError:
		title_string = ""	

	return title_string

# Function to extract Product Price
def get_price(soup):

	try:
		price = soup.find("span", attrs={'id':'priceblock_ourprice'}).string.strip()

	except AttributeError:
		price = ""	

	return price

# Function to extract Product Rating
def get_rating(soup):

	try:
		rating = soup.find("i", attrs={'class':'a-icon a-icon-star a-star-4-5'}).string.strip()
		
	except AttributeError:
		
		try:
			rating = soup.find("span", attrs={'class':'a-icon-alt'}).string.strip()
		except:
			rating = ""	

	return rating

# Function to extract Number of User Reviews
def get_review_count(soup):
	try:
		review_count = soup.find("span", attrs={'id':'acrCustomerReviewText'}).string.strip()
		
	except AttributeError:
		review_count = ""	

	return review_count

# Function to extract Availability Status
def get_availability(soup):
	try:
		available = soup.find("div", attrs={'id':'availability'})
		available = available.find("span").string.strip()

	except AttributeError:
		available = ""	

	return available	

if __name__ == '__main__':

	# Headers for request
	HEADERS = ({'User-Agent':
	            'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36',
	            'Accept-Language': 'en-US, en;q=0.5'})

	# The webpage URL
	URL = "https://www.amazon.com/Sony-PlayStation-Pro-1TB-Console-4/dp/B07K14XKZH/"

	# HTTP Request
	webpage = requests.get(URL, headers=HEADERS)

	# Soup Object containing all data
	soup = BeautifulSoup(webpage.content, "lxml")

	# Function calls to display all necessary product information
	print("Product Title =", get_title(soup))
	print("Product Price =", get_price(soup))
	print("Product Rating =", get_rating(soup))
	print("Number of Product Reviews =", get_review_count(soup))
	print("Availability =", get_availability(soup))
	print()
	print()


산출:

Product Title = Sony PlayStation 4 Pro 1TB Console - Black (PS4 Pro)
Product Price = $473.99
Product Rating = 4.7 out of 5 stars
Number of Product Reviews = 1,311 ratings
Availability = In Stock.

단일 Amazon 웹 페이지에서 정보를 추출하는 방법을 알았으므로 URL만 변경하여 동일한 스크립트를 여러 웹 페이지에 적용할 수 있습니다.

또한 이제 Amazon 검색 결과 웹 페이지에서 링크를 가져와 보겠습니다.

Amazon 검색 결과 웹 페이지에서 링크 가져오기

이전에 우리는 임의의 PlayStation 4에 대한 정보를 얻었습니다. 가격과 등급을 비교하기 위해 여러 PlayStation에 대해 이러한 정보를 추출하는 것은 유용한 아이디어입니다.

href 속성 값으로 < > 태그로 묶인 링크를 찾을 수 있습니다.

단일 링크를 가져오는 대신 find_all() 함수를 사용하여 유사한 모든 링크를 추출할 수 있습니다.

# Fetch links as List of Tag Objects
links = soup.find_all("a", attrs={'class':'a-link-normal s-no-outline'})

find_all() 함수는 여러 개의 Tag 개체를 포함하는 반복 가능한 개체를 반환합니다. 결과적으로 각 태그 개체를 선택하고 href 속성의 값으로 저장된 링크를 뽑아냅니다.

# Store the links
links_list = []

# Loop for extracting links from Tag Objects
for link in links:
	links_list.append(link.get('href'))

각 링크를 반복하고 제품 세부 정보를 추출할 수 있도록 목록 안에 링크를 저장합니다.

# Loop for extracting product details from each link 
	for link in links_list:
		
		new_webpage = requests.get("https://www.amazon.com" + link, headers=HEADERS)
		new_soup = BeautifulSoup(new_webpage.content, "lxml")
		
		print("Product Title =", get_title(new_soup))
		print("Product Price =", get_price(new_soup))
		print("Product Rating =", get_rating(new_soup))
		print("Number of Product Reviews =", get_review_count(new_soup))
		print("Availability =", get_availability(new_soup))

제품 정보 추출을 위해 이전에 생성된 기능을 재사용합니다. 여러 수프를 생산하는 이 프로세스는 코드를 느리게 만들지 만 차례로 여러 모델과 거래 간의 적절한 가격 비교를 제공합니다.

여러 웹 페이지에서 제품 세부 정보를 추출하는 Python 스크립트

다음은 여러 PlayStation 거래를 나열하기 위한 완전한 작업 Python 스크립트입니다.

from bs4 import BeautifulSoup
import requests

# Function to extract Product Title
def get_title(soup):
	
	try:
		# Outer Tag Object
		title = soup.find("span", attrs={"id":'productTitle'})

		# Inner NavigatableString Object
		title_value = title.string

		# Title as a string value
		title_string = title_value.strip()

		# # Printing types of values for efficient understanding
		# print(type(title))
		# print(type(title_value))
		# print(type(title_string))
		# print()

	except AttributeError:
		title_string = ""	

	return title_string

# Function to extract Product Price
def get_price(soup):

	try:
		price = soup.find("span", attrs={'id':'priceblock_ourprice'}).string.strip()

	except AttributeError:

		try:
			# If there is some deal price
			price = soup.find("span", attrs={'id':'priceblock_dealprice'}).string.strip()

		except:		
			price = ""	

	return price

# Function to extract Product Rating
def get_rating(soup):

	try:
		rating = soup.find("i", attrs={'class':'a-icon a-icon-star a-star-4-5'}).string.strip()
		
	except AttributeError:
		
		try:
			rating = soup.find("span", attrs={'class':'a-icon-alt'}).string.strip()
		except:
			rating = ""	

	return rating

# Function to extract Number of User Reviews
def get_review_count(soup):
	try:
		review_count = soup.find("span", attrs={'id':'acrCustomerReviewText'}).string.strip()
		
	except AttributeError:
		review_count = ""	

	return review_count

# Function to extract Availability Status
def get_availability(soup):
	try:
		available = soup.find("div", attrs={'id':'availability'})
		available = available.find("span").string.strip()

	except AttributeError:
		available = "Not Available"	

	return available	


if __name__ == '__main__':

	# Headers for request
	HEADERS = ({'User-Agent':
	            'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36',
	            'Accept-Language': 'en-US'})

	# The webpage URL
	URL = "https://www.amazon.com/s?k=playstation+4&ref=nb_sb_noss_2"
	
	# HTTP Request
	webpage = requests.get(URL, headers=HEADERS)

	# Soup Object containing all data
	soup = BeautifulSoup(webpage.content, "lxml")

	# Fetch links as List of Tag Objects
	links = soup.find_all("a", attrs={'class':'a-link-normal s-no-outline'})

	# Store the links
	links_list = []

	# Loop for extracting links from Tag Objects
	for link in links:
		links_list.append(link.get('href'))


	# Loop for extracting product details from each link 
	for link in links_list:

		new_webpage = requests.get("https://www.amazon.com" + link, headers=HEADERS)

		new_soup = BeautifulSoup(new_webpage.content, "lxml")
		
		# Function calls to display all necessary product information
		print("Product Title =", get_title(new_soup))
		print("Product Price =", get_price(new_soup))
		print("Product Rating =", get_rating(new_soup))
		print("Number of Product Reviews =", get_review_count(new_soup))
		print("Availability =", get_availability(new_soup))
		print()
		print()

산출:

Product Title = SONY PlayStation 4 Slim 1TB Console, Light & Slim PS4 System, 1TB Hard Drive, All the Greatest Games, TV, Music & More
Product Price = $357.00
Product Rating = 4.4 out of 5 stars
Number of Product Reviews = 32 ratings
Availability = In stock on September 8, 2020.


Product Title = Newest Sony PlayStation 4 PS4 1TB HDD Gaming Console Bundle with Three Games: The Last of Us, God of War, Horizon Zero Dawn, Included Dualshock 4 Wireless Controller
Product Price = $469.00
Product Rating = 4.6 out of 5 stars
Number of Product Reviews = 211 ratings
Availability = Only 14 left in stock - order soon.


Product Title = PlayStation 4 Slim 1TB Console - Fortnite Bundle
Product Price = 
Product Rating = 4.8 out of 5 stars
Number of Product Reviews = 2,715 ratings
Availability = Not Available


Product Title = PlayStation 4 Slim 1TB Console - Only On PlayStation Bundle
Product Price = $444.00
Product Rating = 4.7 out of 5 stars
Number of Product Reviews = 5,190 ratings
Availability = Only 1 left in stock - order soon.

위의 Python 스크립트는 PlayStation 목록에 국한되지 않습니다. URL을 헤드폰이나 이어폰과 같은 Amazon 검색 결과에 대한 다른 링크로 전환할 수 있습니다.

앞에서 언급했듯이 HTML 페이지의 레이아웃과 태그는 시간이 지남에 따라 변경될 수 있으므로 이와 관련하여 위의 코드는 쓸모가 없습니다. 그러나 독자는 이 기사에서 배운 웹 스크래핑의 개념과 기술을 집으로 가져와야 합니다.

결론

Web Scraping은 "상품 가격 비교\부터 "소비자 성향 분석\까지 다양한 이점이 있을 수 있습니다. 누구나 인터넷에 접근할 수 있고 파이썬은 매우 쉬운 언어이기 때문에 누구나 필요에 따라 웹 스크래핑을 수행할 수 있습니다.

이 기사가 이해하기 쉬웠기를 바랍니다. 질문이나 의견이 있으시면 언제든지 아래에 댓글을 달아주세요. 그때까지 해피 스크래핑!!!.