Как создать цикл парсера статей с помощью Apscheduler в Django
У меня есть сценарий на Django, который помогает мне разбирать RSS-каналы для моего ежедневного потребления. Пока что он справляется с поставленной задачей. Он создал 3 модели:
class Categories(models.Model):
category_name = models.CharField(max_length=50, verbose_name='Categories')
''' Categories = ['Business', Sports, Politics, Tech] '''
class FeedSource(models.Model):
feed_url = models.URLField(verbose_name='RSS Feed Link')
''' FeedSource = ['http://rss.cnn.com/rss/edition.rss', ''https://www.espn.com/espn/rss/news, 'http://rss.politico.com/politics.xml'] '''
class Posts(models.Model):
...
source = models.ForeignKey(FeedSource, on_delete=models.CASCADE, verbose_name='Source')
category = models.ForeignKey(Categories, on_delete=models.CASCADE, verbose_name='Category')
Команда Apscheduler выглядит следующим образом. Как вы можете видеть, в fetch_articles functions
, которые разбирают разные ссылки, есть немного повторений, потому что каждая ссылка принадлежит разным Feedsource
& Category
. То же самое относится и к Handle function
. Каждый fetch_articles function
имеет свой собственный планировщик.
import logging
from django.conf import settings
from django.core.management.base import BaseCommand
from apscheduler.schedulers.blocking import BlockingScheduler
from django_apscheduler.jobstores import DjangoJobStore
from Posts.models import Posts, FeedSource, Categories
import time
logger = logging.getLogger(__name__)
def save_new_articles(feed, source_id, category_id):
"""Function that parses & saves new articles to DB"""
...
if not Posts.objects.filter(guid=item.guid).exists():
post = Posts(
...
guid = item.guid,
source_id = selected_source_id
category_id = selected_category_id
...
)
post.save()
def fetch_siteA_articles():
"""Fetches news artices from siteA"""
feed = feedparser.parse("siteA")
source = FeedSource.objects.get(pk=1)
source_id = int(source.pk)
category = Categories.objects.get(pk=3)
category_id = int(source.pk)
save_new_articles(feed, source_id, category_id)
def fetch_siteB_articles():
"""Fetches news artices from siteB"""
feed = feedparser.parse("siteB")
source = FeedSource.objects.get(pk=2)
source_id = int(source.pk)
category = Categories.objects.get(pk=1)
category_id = int(source.pk)
save_new_articles(feed, source_id, category_id)
def fetch_siteC_articles():
"""Fetches news artices from siteC"""
feed = feedparser.parse("siteC")
source = FeedSource.objects.get(pk=3)
source_id = int(source.pk)
category = Categories.objects.get(pk=2)
category_id = int(source.pk)
save_new_articles(feed, source_id, category_id)
class Command(BaseCommand):
help = "Runs apscheduler."
def handle(self, *args, **options):
scheduler = BlockingScheduler(timezone=settings.TIME_ZONE)
scheduler.add_jobstore(DjangoJobStore(), "default")
scheduler.add_job(fetch_siteA_articles, trigger = "interval", minutes = 15, id = "siteA News Articles", max_instances = 1, replace_existing = True)
logger.info("Added job: siteA Articles.")
time.sleep(10)
scheduler.add_job(fetch_siteB_articles, trigger = "interval", minutes = 15, id="siteB News Articles", max_instances = 1, replace_existing = True,)
logger.info("Added job: siteB Articles.")
time.sleep(10)
scheduler.add_job(fetch_siteC_articles, trigger = "interval", minutes = 15, id = "siteC News Articles", max_instances = 1, replace_existing = True)
logger.info("Added job: siteC Articles.")
time.sleep(10)
try:
logger.info("Starting scheduler...")
scheduler.start()
except KeyboardInterrupt:
logger.info("Stopping scheduler...")
scheduler.shutdown()
logger.info("Scheduler shut down successfully!")
В настоящее время я жестко закодировал ссылки в функциях, но в идеале я хотел бы получать их из модели Feedsource
. Я хотел бы добавить больше ссылок, но я не хочу продолжать повторять их дальше. Существует ли эффективный способ получения ссылок из Feedsource
& циклического перебора ссылок при присоединении их к различным source_id
& category_id
? Эта же помощь относится к созданию цикла for в функции Handle
для перебора расписаний.
Любая помощь по этим вопросам будет высоко оценена.