

این مقاله عملی و مرحلهبهمرحله به شما نشان میدهد چطور دادههای استخراجشده با Scrapy را ذخیره کنید. پس از خواندن این مطلب میدانید چه روشهایی برای خروجیگیری (فایلهای CSV/JSON، S3، یا پایگاهداده) وجود دارد، چه نکات امنیتی و عملکردی را باید رعایت کنید و چگونه یک Item Pipeline برای ذخیره در MySQL یا PostgreSQL بنویسید.
Scrapy بهصورت داخلی قابلیتهایی برای صادر کردن خروجی دارد که به آنها «Feed Exporters» گفته میشود. این قابلیت برای خروجیهای سریع و یکبارمصرف بسیار مناسب است.
Feed Exporter مناسب کارهای ساده یا زمانی است که نیاز به پردازش پیچیده روی هر آیتم ندارید. برای منطق ذخیرهسازی پیشرفتهتر از Item Pipelines استفاده کنید.
برای کارهای ساده و یکباره میتوانید از فلگهای خط فرمان استفاده کنید. توجه کنید بین -o و -O تفاوت وجود دارد: -o به خروجی اضافه میکند (append) و -O فایل را بازنویسی (overwrite) میکند.
مثال ذخیره به JSON:
scrapy crawl chocolatespider -o my_scraped_chocolate_data.json
مثال ذخیره با مسیر کامل و نوع مشخص:
scrapy crawl chocolatespider -O file:///path/to/project/my_scraped_chocolate_data.json:json
ذخیره به CSV:
scrapy crawl chocolatespider -o my_scraped_chocolate_data.csv
# یا با مسیر کامل
scrapy crawl chocolatespider -O file:///path/to/project/my_scraped_chocolate_data.csv:csv
نکات عملی:
برای ارسال خروجی مستقیم به S3 باید یکی از کتابخانههای AWS مثل botocore یا boto3 را نصب کنید. با این کار میتوانید URI مقصد را با قالب s3:// مشخص کنید. مثال نصب:
pip3 install botocore
مثال اجرای کرال و ارسال خروجی به S3 (پارامترها را با مقادیر خودتان جایگزین کنید):
scrapy crawl chocolatespider -O s3://AWS_KEY:AWS_SECRET@mybucket/path/myscrapeddata.csv:csv
روش امنتر: ذخیره کردن کلیدها در فایل تنظیمات پروژه:
AWS_ACCESS_KEY_ID = 'myaccesskeyhere'
AWS_SECRET_ACCESS_KEY = 'mysecretkeyhere'
هشدارهای امنیتی و عملکردی:
برای ذخیره در پایگاهداده بهتر است از Item Pipelines استفاده کنید تا هر آیتم هنگام استخراج، پردازش و ذخیره شود. مراحل کلی:
نمونه DDL برای ایجاد جدول (مثال):
CREATE TABLE IF NOT EXISTS chocolate_products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
price VARCHAR(255),
url TEXT
);
نمونه پیادهسازی ساده Pipeline برای MySQL (پارامترها را از متغیرهای محیطی بخوانید؛ هرگز مقادیر را هاردکد نکنید):
import mysql.connector
import os
class SavingToMySQLPipeline(object):
def __init__(self):
self.create_connection()
def create_connection(self):
# ورودیها: پارامترهای اتصال از محیط یا settings
self.connection = mysql.connector.connect(
host=os.getenv('DB_HOST', 'localhost'),
user=os.getenv('DB_USER', 'root'),
password=os.getenv('DB_PASS', ''),
database=os.getenv('DB_NAME', 'chocolate_scraping')
)
self.curr = self.connection.cursor()
def process_item(self, item, spider):
# این متد توسط Scrapy برای هر آیتم صدا زده میشود
self.store_db(item)
return item
def store_db(self, item):
# استفاده از query پارامتری برای جلوگیری از SQL injection
sql = "INSERT INTO chocolate_products (name, price, url) VALUES (%s, %s, %s)"
values = (item.get('name'), item.get('price'), item.get('url'))
self.curr.execute(sql, values)
self.connection.commit()
توضیح خطها:
نکات عملی برای MySQL:
برای PostgreSQL باید درایور psycopg2 را نصب کنید و در queryها دقت کنید که placeholderها در psycopg2 هم از %s استفاده میکنند.
pip install psycopg2
نمونه اتصال و pipeline برای PostgreSQL:
import psycopg2
import os
class SavingToPostgresPipeline(object):
def __init__(self):
self.create_connection()
def create_connection(self):
self.connection = psycopg2.connect(
host=os.getenv('DB_HOST', 'localhost'),
database=os.getenv('DB_NAME', 'chocolate_scraping'),
user=os.getenv('DB_USER', 'postgres'),
password=os.getenv('DB_PASS', '')
)
self.curr = self.connection.cursor()
def process_item(self, item, spider):
self.store_db(item)
return item
def store_db(self, item):
try:
self.curr.execute(
"INSERT INTO chocolate_products (name, price, url) VALUES (%s, %s, %s)",
(item.get('name'), item.get('price'), item.get('url'))
)
self.connection.commit()
except Exception as e:
# لاگبرداری خطا و rollback در صورت لزوم
print(e)
self.connection.rollback()
نکات خاص PostgreSQL:
پس از نوشتن Pipeline فراموش نکنید آن را در settings.py ثبت کنید تا Scrapy آن را اجرا کند. مثال:
ITEM_PIPELINES = {
'chocolatescraper.pipelines.PriceToUSDPipeline': 100,
'chocolatescraper.pipelines.DuplicatesPipeline': 200,
'chocolatescraper.pipelines.SavingToMySQLPipeline': 300,
}
ترتیب عددی مشخصکننده اولویت اجرا است؛ عدد پایینتر زودتر اجرا میشود.
خلاصه: اگر نیاز به خروجی ساده دارید از Feed Exporter استفاده کنید؛ برای منطق ذخیرهسازی پیچیده، پاکسازی پیشرفته یا ذخیره در DB بهتر است از Item Pipelines بهره ببرید. برای ارسال به S3 از کتابخانه AWS مناسب و مکانیسمهای امن نگهداری کلیدها استفاده کنید. در نهایت عملکرد و پایداری را با batching، retry و استفاده از نقشهای IAM/متغیرهای محیطی بهبود دهید.
قدم بعدی منطقی شما میتواند مدیریت User-Agentها، پراکسیها و استقرار (deployment) کرالها باشد تا رباتتان در محیط تولیدی پایدار و امن اجرا شود.


