2017-09-13 4 views
0

Ich bin neu in der Programmierung und das ist mein erstes Projekt. Bis jetzt habe ich durch Googeln, Tutorials und Stack zusammengestellt was ich habe.Benötigt APScheduler eine Funktion zum Ausführen?

Ich versuche, Daten von einem Pandas df von abgeschabten RSS-Feeds zu einer Remote-SQL-Datenbank hinzuzufügen, dann hosten das Skript auf Heroku oder AWS und lassen Sie das Skript jede Stunde ausgeführt werden.

Jemand auf here recommend, die ich APScheduler as in this post verwenden.

Ich habe Probleme, da es keine Dummies Tutorials um APScheduler gibt. Das habe ich bisher erstellt.

Ich denke, meine Frage ist mein Skript muss in einer Funktion für APScheduler sein, um es auszulösen oder kann es anders funktionieren.

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' 

Antwort

0

Ja. Was Sie ausführen möchten, muss eine Funktion (oder eine andere aufrufbare, wie eine Methode) sein. Die Dekoratorsyntax (@sched.…) benötigt eine Funktionsdefinition (def …), auf die der Decorator angewendet wird. Der Code in Ihrem Beispiel wird nicht kompiliert.

Dann ist es ein Scheduler blockiert, was bedeutet, wenn Sie sched.start() diese Methode aufrufen, kehrt nicht (es sei denn, Sie den Scheduler in einigen geplanten Code stoppen) und nichts, nachdem der Anruf ausgeführt wird.

Die Importe sollten nach oben gehen, dann ist es einfacher zu sehen, worauf das Modul angewiesen ist. Und importiere Dinge, die du nicht benutzt.

Ich bin mir nicht sicher, warum Sie importieren und pandas für Daten verwenden, die nicht wirklich DataFrame Objekte benötigen. Auch SQLAlchemy ohne tatsächlich diese Bibliothek mit etwas bietet und Formatierung Werte als Zeichenfolgen in einer SQL-Abfrage, die is dangerous!

Nur mit SQLAlchemy für die Datenbank es wie folgt aussehen:

#!/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() 

Die Zeitspalte scheint ein etwas komisch, hätte ich hier eine TIMESTAMP oder erwartet und nicht eine Zeichenfolge, die viel von der Information wegwirft, nur den abgekürzten Wochentag und die Zeit verlassend.

+0

danke! Ich muss dein Skript durchlesen, um zu verstehen, wie du das getan hast. Es ist so sauber im Vergleich zu meinem. Was die Pandas betrifft, begann ich mit dem Einlesen und Weiterentwickeln. Ich wusste, dass es nicht richtig war, aber es funktionierte und ich wollte es nicht unterbrechen, bevor ich mein erstes Ziel erreichen konnte und es in eine Datenbank schickte. Ich schaue mir an, wie sich die Zeit zu einem TIMESTAMP ändert, das habe ich versucht zu erreichen. Kann ich SQLAlchemy ohne pymysql verwenden? –

+1

Sie müssen _a_ Modul haben, um mit der MySQL-Datenbank zu sprechen, es muss nicht "pymysql" sein. Die SQLAlchemy-Dokumentation [listet alle unterstützten Module zur Verbindung mit MySQL auf] (http://docs.sqlalchemy.org/en/latest/dialects/mysql.html) und ihre Funktionen/Einschränkungen. – BlackJack

+0

Ich bekomme immer einen KeyError. Ich löschte und neu erstellt die Tabelle und es tritt immer noch Traceback (letzten Aufruf zuletzt): Datei "/usr/local/lib/python3.5/dist-packages/apscheduler/executors/base.py", Zeile 125, in run_job retval = job.func (* job.args, ** job.kwargs) Datei "", Zeile 20, in process_feeds rstracker = Metadaten.tables ['rstracker'] KeyError: 'rstracker' –

Verwandte Themen