Django项目内新闻爬虫的运行与定时调度实现需求及代码说明
没问题,咱们来搞定你这个集成在Django里的新闻爬虫的运行和定时调度问题。先梳理下你现有的代码基础,再一步步讲手动运行和定时任务的实现方式。
在Django项目中实现Scrapy新闻爬虫的运行与定时调度
1. 现有代码梳理
先确认下你已经写好的核心代码:
爬虫核心文件(spiders/news_spider.py)
class NewsSpider(CrawlSpider): name = "news" start_urls = ['https://zeenews.india.com/latest-news'] def start_requests(self): urls = ['https://zeenews.india.com/latest-news'] for url in urls: yield scrapy.Request(url=url, callback=self.parse) def parse(self, response): item = NewsScraperItem() data = response.css('div.sec-con-box') item['headlines'] = data.css('h3::text').extract_first() item['content'] = data.css('p::text').extract_first() return item
Items配置文件(items.py)
import scrapy from scrapy_djangoitem import DjangoItem from news.models import LatestNews class NewsScraperItem(DjangoItem): django_model = LatestNews
⚠️ 小提醒:你的parse方法目前只抓取了第一个sec-con-box的内容,会漏掉页面上的其他新闻,建议改成遍历所有目标元素:
def parse(self, response): # 遍历页面上所有新闻区块 for data in response.css('div.sec-con-box'): item = NewsScraperItem() item['headlines'] = data.css('h3::text').extract_first() item['content'] = data.css('p::text').extract_first() yield item
2. 手动运行爬虫
因为是嵌入Django的Scrapy项目,需要让Scrapy识别Django的环境配置,推荐两种运行方式:
方式一:直接用Scrapy命令运行
在项目根目录下,先设置Django环境变量,再执行爬虫命令:
# Linux/macOS export DJANGO_SETTINGS_MODULE=你的Django项目名.settings scrapy crawl news # Windows(命令提示符) set DJANGO_SETTINGS_MODULE=你的Django项目名.settings scrapy crawl news # Windows(PowerShell) $env:DJANGO_SETTINGS_MODULE = "你的Django项目名.settings" scrapy crawl news
方式二:通过Django自定义管理命令运行
这种方式更贴合Django项目的使用习惯,不用每次手动设置环境变量:
- 在你的Django app(比如
news)下创建management/commands目录,新建run_news_spider.py文件:
from django.core.management.base import BaseCommand from scrapy.crawler import CrawlerProcess from scrapy.utils.project import get_project_settings from 你的Scrapy项目名.spiders.news_spider import NewsSpider class Command(BaseCommand): help = '运行新闻爬虫' def handle(self, *args, **options): process = CrawlerProcess(get_project_settings()) process.crawl(NewsSpider) process.start()
- 直接通过Django命令运行:
python manage.py run_news_spider
3. 定时调度爬虫
要实现自动定时运行,推荐用Celery + Celery Beat,它和Django的集成度很高,适合长期运行的定时任务场景。
步骤1:安装依赖
pip install celery redis django-celery-beat
步骤2:配置Celery
在Django项目的settings.py中添加以下配置:
# Celery核心配置 CELERY_BROKER_URL = 'redis://localhost:6379/0' CELERY_RESULT_BACKEND = 'redis://localhost:6379/0' CELERY_ACCEPT_CONTENT = ['json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' # 启用Django-Celery-Beat定时任务管理 INSTALLED_APPS += ['django_celery_beat']
步骤3:创建Celery实例
在项目根目录新建celery.py文件:
import os from celery import Celery from django.conf import settings os.environ.setdefault('DJANGO_SETTINGS_MODULE', '你的Django项目名.settings') app = Celery('你的Django项目名') app.config_from_object('django.conf:settings', namespace='CELERY') app.autodiscover_tasks()
然后在项目根目录的__init__.py中添加:
from .celery import app as celery_app __all__ = ('celery_app',)
步骤4:编写定时任务函数
在你的Django app(比如news)下新建tasks.py:
from celery import shared_task from scrapy.crawler import CrawlerProcess from scrapy.utils.project import get_project_settings from 你的Scrapy项目名.spiders.news_spider import NewsSpider @shared_task def run_news_spider(): process = CrawlerProcess(get_project_settings()) process.crawl(NewsSpider) process.start()
步骤5:配置定时任务
有两种配置方式,选一种就行:
方式一:通过Django Admin后台配置
先执行迁移创建定时任务所需的数据库表:python manage.py migrate启动Django服务后登录Admin后台,找到
Periodic tasks(周期任务),新建任务:- 选择任务为
news.tasks.run_news_spider - 设置执行周期(比如每天凌晨1点、每小时一次等)
- 保存后Celery Beat会自动按照配置执行任务
- 选择任务为
方式二:代码中硬编码配置
在settings.py中添加:from celery.schedules import crontab CELERY_BEAT_SCHEDULE = { # 每小时运行一次爬虫 'run-news-spider-every-hour': { 'task': 'news.tasks.run_news_spider', 'schedule': crontab(minute=0, hour='*/1'), }, # 也可以设置每天凌晨1点运行:crontab(minute=0, hour=1) }
步骤6:启动Celery服务
最后启动Celery Worker(执行任务)和Celery Beat(调度定时任务):
# 启动Celery Worker celery -A 你的Django项目名 worker --loglevel=info # 启动Celery Beat celery -A 你的Django项目名 beat --loglevel=info
注意事项
- 确保你的
LatestNews模型字段和NewsScraperItem完全对应(比如模型里要有headlines和content字段) - 如果爬虫运行时找不到Django模型,检查
scrapy.cfg是否配置了Django路径:[settings] default = 你的Scrapy项目名.settings [django] settings_module = 你的Django项目名.settings - 生产环境建议用
systemd或supervisor管理Celery进程,确保它们持续运行
内容的提问来源于stack exchange,提问作者Hetvee Sanghani




