В новинку для Ubuntu, и в первый раз пишущий crontab, или с помощью редактора Nano. В основном я могу заставить простой сценарий Python стрелять через crontab, но не фактический сценарий Python должен был быть запланирован. Ниже то, что я сделал.
Я могу запустить этот простой скрипт Python (названный testChronScript.py) через crontab:
#!/usr/bin/python
# -*- coding: utf-8 -*-
print "TESTING"
file_name = "test_outputfile.txt"
output = open(file_name, "w")
output.write("TEST")
print "DONE"
Путем я устанавливаю вкладку крона, и получающийся вывод похож на это:
justin@JBot:~/PycharmProjects/Quant_Local$ sudo nano runScripts.cron
justin@JBot:~/PycharmProjects/Quant_Local$ crontab runScripts.cron
justin@JBot:~/PycharmProjects/Quant_Local$ crontab -l
41 14 * * * python testChronScript.py > /dev/pts/19
justin@JBot:~/PycharmProjects/Quant_Local$ TESTING
DONE
Этот сценарий Python будет работать в 14:41 точно так же, как он был присвоен, и создайте файл в каталоге.
Теперь фактический сценарий, который я пытаюсь установить через crontab, очищает данные из Википедии и сохраняет его к базе данных. Вот код:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Author: Justin Dano 8/6/2016
# This script was inspired by Michael Halls-Moore articles on Quantstart.com
import datetime
import lxml.html
from urllib2 import urlopen
from math import ceil
from SharedFunctionsLib import *
def scrape_sp500_symbols():
"""
Scrape S&P500 symbols from Wikipedia page
:return: List of current SP500 symbols
"""
timestamp = datetime.datetime.utcnow()
# Use libxml to scrape S&P500 ticker symbols
page = urlopen('http://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
page = lxml.html.parse(page)
symbols_list = page.xpath('//table[1]/tr')[1:]
# Obtain the ticker symbol, name, and sector information
# for each row in the S&P500 constituent table
ticker_symbols = []
for symbol in symbols_list:
tds = symbol.getchildren()
sd = {'ticker': tds[0].getchildren()[0].text,
'name': tds[1].getchildren()[0].text,
'sector': tds[3].text}
# Map ticker information to the columns of our database table
# The first value (2) represents the status id, which is set to live by default
ticker_symbols.append((2, sd['ticker'], sd['name'],
sd['sector'], timestamp, timestamp))
return ticker_symbols
def filter_symbols(symbols):
"""
If we are updating our symbols table, we do not want to
add duplicate symbols, so here we filter out companies
that already exist in the database.
:param symbols: The list of symbols scraped from Wikipedia
:return: List of symbols not yet represented in database
"""
new_symbols = []
unique_symbols = set()
# Attempt to get any existing ticker data
data = retrieve_db_tickers(con)
# Collect a set of existing tickers
for symbol in data:
unique_symbols.add(symbol[1])
# Now add any additional symbols not yet included in the
# database from the SP500 wiki page
for s in symbols:
if s[0] not in unique_symbols:
print(str(s[2]) + " will be added to the database!")
new_symbols.append(s)
return new_symbols
def insert_sp500_symbols(symbols):
"""
Insert any new S&P500 symbols (that do not already belong)
into the MySQL database.
:param symbols: List of tuples where each tuple is data for a specific company
"""
# Create the insert query
column_fields = "status_id, ticker, name, sector, created_date, last_updated_date"
insert_fields = ("%s, " * 6)[:-2]
query_string = "INSERT INTO symbol (%s) VALUES (%s)" % (column_fields, insert_fields)
# Insert symbol data into the database for every symbol
with con:
cur = con.cursor()
# This line avoids the MySQL MAX_PACKET_SIZE
# It chunks the inserts into sets of 100 at a time
for i in range(0, int(ceil(len(symbols) / 100.0))):
cur.executemany(query_string, symbols[i*100:(i+1)*100-1])
if __name__ == "__main__":
con = get_db_connection()
# 1.Scrape ticker data for the current companies existing in the S&P500 index from Wikipedia
symbols = scrape_sp500_symbols()
# 2.Filter out pre-existing data that may already belong in our database
filtered_symbols = filter_symbols(symbols)
# 3.Insert company ticker data into our MySQL database
insert_sp500_symbols(filtered_symbols)
Теперь вывод похож на это:
justin@JBot:~/PycharmProjects/Quant_Local$ sudo nano runScripts.cron
justin@JBot:~/PycharmProjects/Quant_Local$ crontab runScripts.cron
justin@JBot:~/PycharmProjects/Quant_Local$ crontab -l
51 14 * * * python obtainSymbols.py > /dev/pts/19
justin@JBot:~/PycharmProjects/Quant_Local$
В основном необходимо видеть некоторый дополнительный вывод (наряду с новыми записями, сохраненными к базе данных.) Сценарий, кажется, не был выполнен, и я не могу выяснить почему!
Вот каталог, доказывающий, что файлы существуют в каталоге и их соответствующих полномочиях.
drwxrwxr-x 3 justin justin 4096 Sep 27 14:50 .
drwxrwxr-x 4 justin justin 4096 Sep 24 14:54 ..
-rw-rw-r-- 1 justin justin 3504 Sep 25 15:02 obtainSymbols.py
-rw-r--r-- 1 root root 52 Sep 27 14:50 runScripts.cron
-rw-rw-r-- 1 justin justin 5009 Sep 27 12:17 SharedFunctionsLib.py
-rw-rw-r-- 1 justin justin 174 Sep 25 16:56 testChronScript.py
Какие-либо предложения на том, почему мой obtainSymbols.py сценарий не будет инициирован моим crontab? Или любые другие предложения о том, как запланировать этот сценарий Python для выполнения (в основном просто ежедневно) очень помогли бы!
Спасибо за внимание.
Перенаправление вывода к текстовому файлу является неправильным. cron
запускает скрипт с sh
, поэтому Ваш cron
, строка должна быть похожей:
41 14 * * * python testChronScript.py >> /dev/pts/19 2>&1
, Когда cron
запускает скрипт, Вы не должны получать вывод к командной строке. Вместо этого проверьте содержание выходного файла с:
cat /dev/pts/19
кроме того, нет никакого смысла в создании runScripts.cron
файл как корень.