파이썬 Playwright와 PyQt를 활용한 웹 스크래핑
안녕하세요! 이번 포스트에서는 Python을 사용하여 무** 쇼핑몰을 크롤링하는 방법에 대해 알아보겠습니다. Playwright를 사용하여 동적 웹페이지를 크롤링하고, PyQt를 이용해 사용자 친화적인 GUI를 만드는 과정을 단계별로 설명하겠습니다.
목차
- 환경 설정
- 기본 크롤링 스크립트 작성
- GUI 애플리케이션 만들기
- 한글 저장 문제 해결
- 주의사항 및 팁
1. 환경 설정
크롤링 프로젝트를 시작하기 전에 필요한 라이브러리를 설치해야 합니다. 다음 명령어를 사용하여 필요한 패키지를 설치하세요:
pip install playwright PyQt5
playwright install chromium
2. 기본 크롤링 스크립트 작성
먼저, Playwright를 사용하여 무** 쇼핑몰을 크롤링하는 기본 스크립트를 작성해 보겠습니다.
from playwright.sync_api import sync_playwright
import csv
import time
def crawl_musinsa(keyword):
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
url = f"https://www.musinsa.com/search/musinsa/integration?q={keyword}&type=keyword"
page.goto(url)
page.wait_for_selector('.sc-1yenj15-0')
# 페이지 스크롤
for _ in range(3):
page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
time.sleep(2)
items = page.query_selector_all('.sc-1yenj15-0')
results = []
for item in items:
# 이미지 URL 추출
img = item.query_selector('.sc-1yenj15-8')
img_url = img.get_attribute('src') or img.get_attribute('data-original') or 'N/A'
# 다른 정보 추출 (브랜드, 상품명, 가격 등)
brand = item.query_selector('.sc-1yenj15-11').inner_text()
name = item.query_selector('.sc-1yenj15-12').inner_text()
price = item.query_selector('.sc-1dubb4w-5').inner_text()
results.append({
'image_url': img_url,
'brand': brand,
'name': name,
'price': price,
})
browser.close()
return results
# 결과를 CSV 파일로 저장
def save_to_csv(results, filename):
with open(filename, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=['image_url', 'brand', 'name', 'price'])
writer.writeheader()
writer.writerows(results)
# 메인 실행 부분
if __name__ == "__main__":
keyword = input("검색할 키워드를 입력하세요: ")
results = crawl_musinsa(keyword)
save_to_csv(results, f'musinsa_{keyword}_results.csv')
print(f"{len(results)}개의 상품 정보를 크롤링하여 저장했습니다.")
이 스크립트는 사용자가 입력한 키워드로 무** 쇼핑몰을 검색하고, 검색 결과의 상품 정보를 크롤링합니다.
3. GUI 애플리케이션 만들기
이제 PyQt를 사용하여 크롤링 스크립트를 제어할 수 있는 GUI 애플리케이션을 만들어 보겠습니다.
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QTextEdit, QProgressBar, QFileDialog
from PyQt5.QtCore import QThread, pyqtSignal
class CrawlerThread(QThread):
update_progress = pyqtSignal(int)
update_status = pyqtSignal(str)
finished = pyqtSignal(list)
def __init__(self, keyword):
QThread.__init__(self)
self.keyword = keyword
def run(self):
results = crawl_musinsa(self.keyword)
self.finished.emit(results)
class CrawlerGUI(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
layout = QVBoxLayout()
input_layout = QHBoxLayout()
self.keyword_input = QLineEdit()
self.crawl_button = QPushButton('크롤링 시작')
input_layout.addWidget(self.keyword_input)
input_layout.addWidget(self.crawl_button)
self.progress_bar = QProgressBar()
self.status_text = QTextEdit()
self.status_text.setReadOnly(True)
layout.addLayout(input_layout)
layout.addWidget(self.progress_bar)
layout.addWidget(self.status_text)
self.setLayout(layout)
self.setWindowTitle('무신사 크롤러')
self.setGeometry(300, 300, 400, 300)
self.crawl_button.clicked.connect(self.start_crawling)
def start_crawling(self):
keyword = self.keyword_input.text()
if not keyword:
self.status_text.setText("키워드를 입력해주세요.")
return
self.crawler_thread = CrawlerThread(keyword)
self.crawler_thread.update_progress.connect(self.update_progress)
self.crawler_thread.update_status.connect(self.update_status)
self.crawler_thread.finished.connect(self.crawling_finished)
self.crawler_thread.start()
self.crawl_button.setEnabled(False)
self.progress_bar.setValue(0)
self.status_text.clear()
def update_progress(self, value):
self.progress_bar.setValue(value)
def update_status(self, status):
self.status_text.append(status)
def crawling_finished(self, results):
self.crawl_button.setEnabled(True)
self.status_text.append(f"크롤링 완료! {len(results)}개의 상품 정보를 가져왔습니다.")
file_path, _ = QFileDialog.getSaveFileName(self, "결과 저장", "", "CSV Files (*.csv)")
if file_path:
save_to_csv(results, file_path)
self.status_text.append(f"결과가 {file_path}에 저장되었습니다.")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = CrawlerGUI()
ex.show()
sys.exit(app.exec_())
이 GUI 애플리케이션은 사용자가 키워드를 입력하고 크롤링을 시작할 수 있는 인터페이스를 제공합니다. 크롤링 진행 상황을 실시간으로 보여주고, 결과를 CSV 파일로 저장할 수 있습니다.
4. 한글 저장 문제 해결
CSV 파일에 한글이 깨져서 저장되는 문제가 발생할 수 있습니다. 이를 해결하기 위해 save_to_csv
함수를 다음과 같이 수정합니다:
import codecs
def save_to_csv(results, filename):
with codecs.open(filename, 'w', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=['image_url', 'brand', 'name', 'price'])
writer.writeheader()
writer.writerows(results)
이렇게 하면 UTF-8 인코딩과 함께 BOM(Byte Order Mark)을 추가하여 Microsoft Excel에서도 한글이 올바르게 표시됩니다.
5. 주의사항 및 팁
- 웹 크롤링 시 해당 웹사이트의 이용약관을 반드시 확인하고 준수해야 합니다.
- 과도한 요청은 서버에 부담을 줄 수 있으므로 적절한 간격을 두고 크롤링해야 합니다.
- 웹사이트의 구조가 변경되면 크롤러가 제대로 작동하지 않을 수 있으므로 주기적으로 코드를 점검해야 합니다.
- 크롤링한 데이터는 개인적인 용도로만 사용하고, 상업적 목적으로 사용하지 않도록 주의해야 합니다.
- 에러 처리와 예외 상황에 대한 대비를 충분히 해두는 것이 좋습니다.
이상으로 무** 쇼핑몰 크롤링 가이드를 마치겠습니다. 이 글이 여러분의 웹 크롤링 프로젝트에 도움이 되었기를 바랍니다. 궁금한 점이나 추가 설명이 필요한 부분이 있다면 댓글로 남겨주세요. 감사합니다!
반응형
'IT > 쇼핑몰' 카테고리의 다른 글
당근마켓에서 신상품 판매하기 (0) | 2024.08.03 |
---|---|
당근마켓으로 시작하는 온라인 사업 (0) | 2024.08.03 |
Angula 11 Shopping Mall Basic (3) llama ai (0) | 2024.05.14 |
Angular 11 Shopping mall Basic (2) (0) | 2024.05.13 |
Angular 11 Shopping Mall Basic(1) (0) | 2024.05.13 |