ここでマルチスレッドの助けを期待しています。私は、現在の時点 (以下のコードの現在の状態) で立ち往生している回答を探すのに 2 日間を費やしました。これをpyscripterで実行すると、(スレッドクラス内で)期待どおりに出力されますが、エラーは発生しません。コードは何らかの方法でスレッドから戻ることができないようです。私はデバッグモードにとどまり、そこから抜け出せず、終わりがありません。すべての助けと忍耐に前もって感謝します。これはマルチスレッドでの私の最初の試みです。
import urllib
import urllib.error
import urllib.request
import datetime
from bs4 import BeautifulSoup
import csv
import threading
import queue
q = queue.Queue()
addrStrList = []
optionsRows = []
class OptionThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
global optionsRows
while True:
webString = self.queue.get()
try:
with urllib.request.urlopen(webString) as url: page = url.read()
currMonth = webString[-2:]
soup = BeautifulSoup(page)
if (soup.text.find('There are no All Markets results for') == -1) & (soup.text.find('is no longer valid') == -1) & (soup.text.find('There is no Options data available') == -1):
tbls = soup.findAll('table')
if len(tbls[9]) > 1:
symb = webString[webString.find("=")+1: webString.find("&")]
expStrings = soup.findAll('td', text=True, attrs={'align': 'right'})[0].contents[0].split()
expDate = datetime.date(int(expStrings[6]), int(currMonth), int(expStrings[5].replace(',', '')))
calls = extract_options(tbls[9], symb, 'Call', expDate)
puts = extract_options(tbls[13], symb, 'Put', expDate)
optionsRows = optionsRows + calls
optionsRows = optionsRows + puts
print("Options extracted for: " + symb + ", ExpDate: " + str(expDate))
except urllib.error.HTTPError as err:
print(err.code)
pass
## if err.code == 404:
## pass
## else:
## raise
class Option:
def __init__(self, UnderlyingSymb, PutCall, Strike, Exp, Symbol, Last, Chg, Bid, Ask, Vol, OpenInt):
self.DateDownloaded = datetime.date.today().strftime('%m/%d/%Y')
self.UnderlyingSymb = UnderlyingSymb
self.PutCall = PutCall
self.Strike = Strike
self.Exp = Exp
self.Symbol = Symbol
self.Last = Last
self.Chg = Chg
self.Bid = Bid
self.Ask = Ask
self.Vol = Vol
self.OpenInt = OpenInt
def ForCsv(self):
return [self.DateDownloaded, self.UnderlyingSymb, self.PutCall, self.Strike, self.Exp.strftime('%m/%d/%Y'), self.Symbol, self.Last,
self.Chg, self.Bid, self.Ask, self.Vol, self.OpenInt]
def get_month(CurrentMonth, MonthsAhead):
cMonth = int(CurrentMonth)
cMonthsAhead = int(MonthsAhead)
if (cMonth + cMonthsAhead > 12):
tempMonth = (cMonth + cMonthsAhead) - 12
else:
tempMonth = cMonth + cMonthsAhead
if (tempMonth < 10):
return '0' + str(tempMonth)
else:
return tempMonth
def extract_options(Options, Underlying, PutCall, Exp):
optionList = []
#Loop over Options to check for null values
for op in range(1, len(Options)):
strike = Options.contents[op].contents[0].string
exp = Exp
symbol = Options.contents[op].contents[1].string
last = Options.contents[op].contents[2].string
change = Options.contents[op].contents[3].string
bid = Options.contents[op].contents[4].string
ask = Options.contents[op].contents[5].string
volume = Options.contents[op].contents[6].string
openInt = Options.contents[op].contents[7].string
if last == None:
last = 0
if change == None:
change = 0
if bid == None:
bid = 0
if ask == None:
ask = 0
if volume == None:
volume = 0
if openInt == None:
openInt = 0
optionList.append(Option(Underlying, PutCall, strike, exp, symbol, last, change, bid, ask,
volume, openInt))
return optionList
def create_address_strings():
#read in symbol list
with open('C:/Users/krice_000/Desktop/MarketResearch/StockSymbolsForTestingThreading.csv', 'rt') as fp:
symbs = [s[0] for s in list(symb for symb in csv.reader(fp))]
#loop over the symbol list and make a list of complete address strings.
#http://finance.yahoo.com/q/op?s=HOV&m=2013-08 (Aug 2013 options chain)
baseStr = 'http://finance.yahoo.com/q/op?s='
dayVar = datetime.date.today()
thisMonth = str(dayVar.month)
thisYear = str(dayVar.year)
for symb in symbs:
for month in range(1,13):
currMonth = get_month(thisMonth, month)
if (int(currMonth) < int(thisMonth)):
currYear = (int(thisYear) + 1)
else:
currYear = thisYear
addrStrList.append(baseStr + symb + '&m=' + str(currYear) + '-' + str(currMonth))
def write_options_to_csv():
opts = [0] * (len(optionsRows))
for option in range(0, len(optionsRows)):
opts[option] = optionsRows[option].ForCsv()
#Write to the csv file.
with open('C:/OptionsChains.csv', 'a', newline='') as fp:
a = csv.writer(fp, delimiter=',')
a.writerows(opts)
def run_proc():
create_address_strings()
for str in addrStrList:
q.put(str)
for i in range(5):
t = OptionThread(q)
#t.name = 'Thread' + str(i)
t.setDaemon(True)
t.start()
q.join()
write_options_to_csv()
if __name__ == '__main__':
run_proc()