1. poetry 설치하기(Mac)
brew install pipx
pipx ensurepath
sudo pipx ensurepath --global #Optional
pipx install poetry
# poetry shell 명령어 사용(가상환경)
poetry self add poetry-plugin-shell
2. MongoDB 설치 및 DB 추가(Mac)
brew tap mongodb/brew
brew update
brew install mongodb-community@8.0
mongod --version
# mongodb 서비스를 백그라운드에서 실행
brew services start mongodb-community@8.0
# mongod 실행(mac)
mongod --config /opt/homebrew/etc/mongod.conf --fork
데이터베이스 관련은 mongodb compass 사용 시 손쉽게 설정할 수 있다.
필자의 경우에는 localhost 27017로 접속하여 books라는 이름의 데이터베이스를 추가했다.
https://www.mongodb.com/ko-kr/products/tools/compass
MongoDB Compass
Explore and interact with your data using Compass, the GUI for MongoDB. Query, modify, delete, and more — all from one interface.
www.mongodb.com
3. poetry init
이미 프로젝트가 존재하는 경우라면 poetry init 명령어로 pyproject.toml(Poetry 설정 파일) 파일을 생성 가능하다.
없는 경우라면 poetry new poetry-demo 명령어로 프로젝트를 생성
4. package install
poetry install
poetry add scrapy
poetry add pymongo
poetry show
poetry install시 poetry.lock 파일이 생성된다.
5. vscode poetry 가상환경 연동
poetry shell 명령어 실행 시 가상환경에 접속되고 아래와 같이 env path가 출력된다.
Virtual environment already activated: /Users/kimjinho/Library/Caches/pypoetry/virtualenvs/books-scraper-wBYwd1Bg-py3.13
해당 경로를 아래와 같은 방식으로 지정해줘야 한다.
vscode -> command + shift + p -> Python: Select Interpreter -> Enter interpreter path...
6. scrapy 시작
해당 명령어 실행 시 폴더구조가 아래와 같이 생성된다.
# 스파이더 생성
scrapy startproject scrapy_test
cd scrapy_test
# 스파이더 생성
scrapy genspider test_spider quotes.toscrape.com
.
├── scrapy.cfg
└── scrapy_test
├── __init__.py
├── items.py
├── middlewares.py
├── pipelines.py
├── settings.py
└── spiders
├── __init__.py
└── test_spider.py
각 파일을 용도는 다음과 같다.
- scrapy.cfg: 프로젝트 설정 파일
- items.py: 데이터 구조 정의
- middlewares.py: 요청/응답 처리 로직
- pipelines.py: 데이터 처리 파이프라인
- settings.py: 프로젝트 설정
- spiders/: 크롤링 로직이 작성된 스파이더 파일
여기서 spiders 폴더에는 각 웹사이트 별로 파싱 로직을 따로 구현한다.
웹사이트에 기생하고 있는 거미라고 생각하니 딱 크롤러 역할과 맞는 것 같다. 이름을 참 잘 지었다.
필자는 크롤링한 데이터를 mongodb에 저장하는 것이 목표이기에 해당 파일들 중 middlewares.py는 사용하지 않았다.
생성된 spiders/test_spider.py 파일의 start_urls를 파싱할 url 전체 경로로 지정해 준다.
class TestSpiderSpider(scrapy.Spider):
name = 'test_spider'
allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/']
7. scrapy 파싱 시작
items.py에 아래와 같이 파싱할 데이터의 타입을 지정해 준다.
import scrapy
class QuoteItem(scrapy.Item):
author = scrapy.Field()
text = scrapy.Field()
tags = scrapy.Field()
test_spider.py에는 파싱 코드를 추가해 준다.
import scrapy
from ..items import QuoteItem
class TestSpiderSpider(scrapy.Spider):
name = 'test_spider'
allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/']
def parse(self, response):
for quote in response.css('div.quote'):
item = QuoteItem()
item['author'] = quote.css('small.author::text').get()
item['text'] = quote.css('span.text::text').re(r'“(.+)”')[0]
item['tags'] = quote.css('div.tags a.tag::text').getall()
print("==============\n", item)
yield item
해당 사이트(http://quotes.toscrape.com/)의 html 구조를 확인해 보면 quote라는 이름의 div에 책 정보들이
차곡차곡 저장되어 있는 것을 확인할 수 있다. 이런 식으로 패턴을 알았다면 해당 div 안에서 필요한 정보의 css를 각각 확인하면 된다.
올바르게 css selecter를 지정했다면 scrapy를 실행해 보자
그냥 실행하면 출력을 알아볼 수 없어서 a라는 파일에 출력내용을 저장했다.
scrapy crawl test_spider > a
실행 후 a 파일을 확인해 보면 아래와 같이 파싱한 내용들을 확인할 수 있다. 파싱은 완료되었다.
7. 파싱 결과를 mongodb에 저장
pipelines.py 에 process_item, from_crawler, open_spider, close_spider 메서드를 추가한다.
process_item 메서드만 필수이고 나머지는 선택이다.
여기서 collection 변수는 추가할 collection 이름이다.
- process_item(self, item, spider):
각 크롤링된 아이템을 처리함 - from_crawler(cls, crawler):
mongo_uri, mongo_db와 같은 설정 정보를 가지는 파이프라인 인스턴스를 생성 - open_spider(self, spider):
크롤러가 열릴 때 호출됨 - close_spider(self, spider):
크롤러가 닫힐 때 호출됨
import pymongo
import sys
from .items import QuoteItem
class ScrapyTestPipeline:
collection = 'books'
def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db
if not self.mongo_uri: sys.exit("You need to provide a MongoDB Connection String using the -s parameter.")
@classmethod
def from_crawler(cls, crawler):
return cls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DATABASE', 'items')
)
def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db]
def close_spider(self, spider):
self.client.close()
def process_item(self, item, spider):
data = dict(QuoteItem(item))
self.db[self.collection].insert_one(data)
return item
로직 순서로 보면 다음과 같다.
1. from_crawler -> __init__ 메서드 순으로 실행되어 초기 설정 정보(mongo_uri, mongo_db)를 저장
2. 크롤러 시작 시 open_spider 메서드가 실행되어 mongodb와 연결됨
3. 각 크롤링 결과를 process_item 메서드에서 mongodb에 추가
4. 크롤러 종료 시 mongodb 연결 끊음
마지막으로 settings.py에 해당 설정을 추가하면 된다.
초기 프로젝트 생성 시 주석으로 추가되어 있다. 여기서 숫자는 우선순위를 의미한다. 낮은 것부터 실행된다.
ITEM_PIPELINES = {
"scrapy_test.pipelines.ScrapyTestPipeline": 300,
}
아래 명령어로 실행 시 mongodb에 차곡차곡 쌓이는 것을 확인할 수 있다.
scrapy crawl test_spider -s MONGO_URI="mongodb://localhost:27017" -s MONGO_DATABASE="books"
참고 URL)
poetry 설치: https://python-poetry.org/docs/
Introduction | Documentation | Poetry - Python dependency management and packaging made easy
pipx is used to install Python CLI applications globally while still isolating them in virtual environments. pipx will manage upgrades and uninstalls when used to install Poetry. Install pipx If pipx is not already installed, you can follow any of the opti
python-poetry.org
poetry setup: https://python-poetry.org/docs/basic-usage/#project-setup
Basic usage | Documentation | Poetry - Python dependency management and packaging made easy
If managing your own virtual environment externally, you do not need to use poetry run since you will, presumably, already have activated that virtual environment and made available the correct python instance. For example, these commands should output the
python-poetry.org
mongodb 설치: https://www.mongodb.com/ko-kr/docs/manual/tutorial/install-mongodb-on-os-x/
macOS에 MongoDB Community Edition 설치 - MongoDB 매뉴얼 v8.0
설치 후 macOS가 mongod 실행을 차단할 수 있습니다. mongod을 시작할 때 개발자를 식별하거나 확인할 수 없다는 보안 오류를 수신한 경우 다음을 실행하여 mongod에 액세스 권한을 부여합니다. 시스템
www.mongodb.com
scrapy 사용: https://docs.scrapy.org/en/latest/topics/commands.html
poetry shell 명령어 사용(가상환경): https://www.reddit.com/r/learnpython/comments/1hxftvw/poetry_shell_the_command_shell_does_not_exist/?rdt=56737
From the learnpython community on Reddit
Explore this post and more from the learnpython community
www.reddit.com
vscode poetry 가상환경 연동: https://takeheed.tistory.com/33
[VSCode] Python 개발 환경 세팅 : Poetry 가상환경
1. Poetry 설치 1.1 Poetry란? Poetry는 pipvenv (pip + virtualenv)와 비슷하게, pip와 virtualenv를 동시에 사용할 수 있게 해주는 packaging과 dependency management를 위한 tool이다. Poetry는 pip와 비교하면 쉽게 이해할 수
takeheed.tistory.com
scrapy pipeline: https://docs.scrapy.org/en/latest/topics/item-pipeline.html