오늘은 HTML과 XML 문서들의 구문을 분석하기 위한 파이썬 라이브러리인 Beautifulsoup를 사용해 볼 것이다.
저번에 무신사의 매거진 페이지 내용을 요약하는 기능을 구현해보았는데,
python 자체 내에서 크롤링까지 진행하면 빠른 속도와 원하는 정보만 추출하기에 유용할 것 같아 사용해보았다.
우리가 사용할 정보량은 많은 편이 아니기에 selenium, scrapy 등 다양한 웹 크롤러 도구들이 있지만
Beautifulsoup를 사용해 볼 것이다.
우선 오늘 크롤링을 진행해볼 페이지이다. (저번 요약 기능 구현에 사용되기도 했다.)
https://www.musinsa.com/cms/news/view/6112
키치한 스트릿 웨어 찾는다면? 유쓰배쓰 주목! | 무신사
'Youth Be At The Head’ 슬로건을 줄여 이름 지은 유쓰배쓰는 세상의 모든 청춘을 응원한다는 의미를 담은 밝은 분위기의 캐주얼 브랜드. 23 S/S 컬렉션은 ‘영 스타 스트리트’ 테마 아래 유쓰배쓰만
www.musinsa.com
필요한 라이브러리를 import해준다.
import requests
import re
from bs4 import BeautifulSoup
크롤링을 원하는 페이지의 url을 넣어주고 해당 페이지의 html 내용을 확인해본다.
#step1 : Download the webpage
url= "https://www.musinsa.com/cms/news/view/6112"
response = requests.get(url)
html_content = response.text
print(response)
print(html_content)
#step2 : Parse the HTML
soup = BeautifulSoup(html_content, 'html.parser')
이제 해당 페이지의 html에서 필요한 부분만 추출해보겠다.
먼저, 매거진의 대표 사진을 가져와보자.
# Find the div with class 'upload-Img'
div = soup.find('div', class_='upload-Img')
# Get the style attribute value
style_attr = div['style']
# Use a regular expression to extract the URL from the style attribute value
image_url_match = re.search(r'url\("(.*?)"\)', style_attr)
# Check if a match was found before trying to access the group method
if image_url_match:
image_url = image_url_match.group(1)
print(image_url)
else:
print("No match found")
매거진의 대표 사진 url을 잘 가져온 것을 확인할 수 있다.
이제 매거진의 제목을 가져와보자.
#step3 : Identify the tags and attributes for the information we need
mg_title = soup.find('title').get_text()
mg_title = mg_title.split('|')[0].strip()
print(mg_title)
<title>키치한 스트릿 웨어 찾는다면? 유쓰배쓰 주목! | 무신사</title> 이 부분에서 텍스트만 가져온 후, |무신사는 제거해주었다.
다음은 매거진의 주요 내용을 알려주는 check point 부분을 가져와보자.
section = soup.find('section', class_='text-checkpoint')
# Find all list items within the section
list_items = section.find_all('li', edittype='text-align')
# Get text content from each list item
for index, li in enumerate(list_items):
text_content = li.span.b.get_text()
print(f"Check Point {index+1}: {text_content}")
다음은 매거진의 본문을 가져와보자.
# Find the section with class 'text-contents'
section = soup.find('section', class_='text-contents')
# Find the <p> tag within the section and get its text content
text_content = section.p.span.get_text()
# Print the extracted text content
print(text_content)
출력된 내용이 길어 첨부하지 않겠지만, 잘 가져온 것을 확인하였다.
이제 매거진 페이지에서 관련 상품 부분을 가져와 리스트로 정리해 볼 것이다.
관련 상품 목록에서 각 상품의 번호, 이미지 url, 상품 url, 브랜드, 상품명, 가격만 가져와보겠다.
goods_units = soup.find_all('li', class_='goods-unit')
for index, unit in enumerate(goods_units):
# Get goods number
goods_no = unit.get('goods_no')
# Get image URL
img_url = unit.find('img', class_='lazy-img').get('data-src')
# Get product URL
product_url = unit.find('div', class_='img').a.get('href')
# Get brand name
brand = unit.find('a', class_='brand').text
# Get product name
product_name = unit.find('a', class_='name').text
# Get product price
price = unit.find('span', class_='price').text
print(f"Goods No: {goods_no}")
print(f"Image URL: {img_url}")
print(f"Product URL: {product_url}")
print(f"Brand: {brand}")
print(f"Product Name: {product_name}")
print(f"Price: {price}")
print("-" * 50) # Separator for each product
마지막으로, 매거진의 저자와 게시일을 가져와서 한 줄로 정리해보자.
# Get the editor name from the HTML part
editor = soup.find('span', class_='opt-editable').get_text()
dates = re.findall(r'\b(?!0000\.00\.00\b)\d{4}\.\d{2}\.\d{2}\b', html_content)
# Print all found dates that are not '0000.00.00'
for date in dates:
date
# Combine the editor name and publication date into the desired format
result = f'{editor}, 게시일 {date}'
print(result)
게시일 날짜 부분은 class로 가져오는데 한계가 있어서 html에서 날짜 형태를 찾은 다음 정리해준 것이다. (추후에 더 정확하게 구현해보겠다)
Beautifulsoup를 사용하여 손쉽게 웹 크롤링을 진행해보았다.
'인공지능 > Generative AI' 카테고리의 다른 글
[6탄] FastAPI 애플리케이션 Google Cloud Run(Docker)에 배포하기 (1) | 2023.11.26 |
---|---|
[5탄] Langchain+GPT+텍스트 임베딩으로 상품에 대한 질의응답하기 (0) | 2023.11.13 |
[4탄] Selenium을 이용한 동적 페이지 크롤링 (1) | 2023.11.13 |
[2탄]Langchain+GPT로 summary와 QA 해보기 (0) | 2023.09.10 |
[1탄] ChatGPT Prompt Engineering & LangChain 을 활용한 온라인 가상 점원 프로젝트 (5) | 2023.05.26 |
댓글