2017-09-13 4 views
0

Je suis nouveau dans le codage et c'est mon premier projet. Jusqu'à présent, j'ai reconstitué ce que j'ai à travers Googling, Tutorials et Stack. J'essaye d'ajouter des données à partir d'un pandas df de flux RSS grattés à une base de données SQL distante, puis j'héberge le script sur heroku ou AWS et j'ai le script en marche toutes les heures.APScheduler a-t-il besoin d'une fonction à exécuter?

Quelqu'un sur here recommend que j'utilise APScheduler as in this post.

Je rencontre des difficultés car il n'y a pas de tutoriels 'mannequins' autour d'APScheduler. C'est ce que j'ai créé jusqu'ici.

Je suppose que ma question est que mon script doit être dans une fonction pour APScheduler pour le déclencher ou peut-il fonctionner d'une autre manière.

from apscheduler.schedulers.blocking import BlockingScheduler 

sched = BlockingScheduler() 

@sched.scheduled_job('interval', minutes=1) 

sched.configure() 
sched.start() 

import pandas as pd 
from pandas.io import sql 
import feedparser 
import time 


rawrss = ['http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml', 
      'https://www.yahoo.com/news/rss/', 
      'http://www.huffingtonpost.co.uk/feeds/index.xml', 
      'http://feeds.feedburner.com/TechCrunch/', 
      'https://www.uktech.news/feed' 
     ] 

time = time.strftime('%a %H:%M:%S') 
summary = 'text' 

posts = [] 
for url in rawrss: 
    feed = feedparser.parse(url) 
    for post in feed.entries: 
     posts.append((time, post.title, post.link, summary)) 

df = pd.DataFrame(posts, columns=['article_time','article_title','article_url', 'article_summary']) # pass data to init 
df.set_index(['article_time'], inplace=True) 

import pymysql 
from sqlalchemy import create_engine 

engine = create_engine('mysql+pymysql://<username>:<host>:3306/<database_name>?charset=utf8', encoding = 'utf-8') 
engine.execute("INSERT INTO rsstracker VALUES('%s', '%s', '%s','%s')" % (time, post.title, post.link, summary)) 

df.to_sql(con=engine, name='rsstracker', if_exists='append') #, flavor='mysql' 

Répondre

0

Oui. Ce que vous voulez exécuter doit être une fonction (ou une autre appelable, comme une méthode). La syntaxe du décorateur (@sched.…) nécessite une définition de fonction (def …) à laquelle le décorateur est appliqué. Le code de votre exemple ne compile pas.

Ensuite, il y a un blocage planificateur, ce qui signifie si vous appelez sched.start() cette méthode ne retourne pas (sauf si vous arrêtez le planificateur dans un code prévu) et rien après l'appel est exécuté.

Les importations devraient aller au sommet, alors il est plus facile de voir de quoi dépend le module. Et ne pas importer des choses que vous n'utilisez pas réellement. Je ne sais pas pourquoi vous importez et utilisez pandas pour les données qui n'ont pas vraiment besoin d'objets DataFrame. Aussi SQLAlchemy sans utiliser quoi que ce soit cette bibliothèque offre et le formatage des valeurs sous forme de chaînes dans une requête SQL qui is dangerous!

Tout en utilisant SQLAlchemy pour la base de données, il peut ressembler à ceci:

#!/usr/bin/env python 
# coding: utf-8 
from __future__ import absolute_import, division, print_function 
from time import strftime 

import feedparser 
from apscheduler.schedulers.blocking import BlockingScheduler 
from sqlalchemy import create_engine, MetaData 

sched = BlockingScheduler() 


RSS_URLS = [ 
    'http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml', 
    'https://www.yahoo.com/news/rss/', 
    'http://www.huffingtonpost.co.uk/feeds/index.xml', 
    'http://feeds.feedburner.com/TechCrunch/', 
    'https://www.uktech.news/feed', 
] 


@sched.scheduled_job('interval', minutes=1) 
def process_feeds(): 
    time = strftime('%a %H:%M:%S') 
    summary = 'text' 

    engine = create_engine(
     'mysql+pymysql://<username>:<host>:3306/<database_name>?charset=utf8' 
    ) 
    metadata = MetaData(engine, reflect=True) 
    rsstracker = metadata.tables['rsstracker'] 

    for url in RSS_URLS: 
     feed = feedparser.parse(url) 
     for post in feed.entries: 
      (
       rsstracker.insert() 
        .values(
         time=time, 
         title=post.title, 
         url=post.link, 
         summary=summary, 
        ) 
        .execute() 
      ) 


def main(): 
    sched.configure() 
    sched.start() 


if __name__ == '__main__': 
    main() 

La colonne de temps semble un un peu bizarre, je me serais attendu à TIMESTAMP ou DATETIME ici et pas une chaîne qui jette une grande partie de l'information, laissant juste le jour de la semaine abrégée et l'heure.

+0

merci! J'ai besoin de lire ton script pour comprendre comment tu as fait ça. C'est tellement bien rangé comparé au mien. En ce qui concerne les Pandas, j'ai commencé par lire et progresser, je savais que ce n'était pas correct mais ça fonctionnait et je ne voulais pas le casser avant que j'arrive à atteindre mon premier objectif, l'envoyer dans une base de données. Je vais essayer de changer l'heure à TIMESTAMP, c'est ce que j'essayais d'accomplir. Puis-je utiliser SQLAlchemy sans pymysql? –

+1

Vous devez avoir un module _a_ pour parler à la base de données MySQL, il ne doit pas être 'pymysql'. La documentation SQLAlchemy [répertorie tous les modules pris en charge pour se connecter avec MySQL] (http://docs.sqlalchemy.org/en/latest/dialects/mysql.html) et leurs fonctionnalités/restrictions. – BlackJack

+0

Je reçois toujours une erreur KeyError. J'ai supprimé et recréé la table et cela se produit toujours Traceback (dernier appel en dernier): Fichier "/usr/local/lib/python3.5/dist-packages/apscheduler/executors/base.py", ligne 125, dans run_job retval = job.func (* travail.args, ** travail.kwargs) Fichier "", ligne 20, dans process_feeds rsstracker = métadonnées.tables ['rsstracker'] KeyError: 'rsstracker' –