IOError:[Errno套接字错误] [Errno 8]节点名称或服务名称提供,或不知道
问题描述:
我试图使用多线程从雅虎财务刮取股票数据并将其保存到SQL。但是,我得到了以下错误:IOError:[Errno套接字错误] [Errno 8]节点名称或服务名称提供,或不知道
*Exception in thread Thread-3091:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "todatabase.py", line 19, in th
htmltext = urllib.urlopen(base).read()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 87, in urlopen
return opener.open(url)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 213, in open
return getattr(self, name)(url)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 350, in open_http
h.endheaders(data)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 1049, in endheaders
self._send_output(message_body)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 893, in _send_output
self.send(msg)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 855, in send
self.connect()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 832, in connect
self.timeout, self.source_address)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 557, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
IOError: [Errno socket error] [Errno 8] nodename nor servname provided, or not known*
这里是我的代码:
from threading import Thread
import sqlite3
import urllib
import re
conn = sqlite3.connect('stock.sqlite')
cur = conn.cursor()
cur.execute('''CREATE TABLE IF NOT EXISTS Stock
(symbol TEXT UNIQUE PRIMARY KEY, price NUMERIC) ''')
dic = {}
def th(ur):
base = "http://finance.yahoo.com/q?s=" + ur
regex = '<span id="yfs_l84_[^.]*">(.+?)</span>'
pattern = re.compile(regex)
htmltext = urllib.urlopen(base).read()
results = re.findall(pattern, htmltext)
try:
dic[ur] = results[0]
except:
print 'got a error!'
symbolslist = open("symbols.txt").read()
symbolslist = symbolslist.split("\n")
threadlist = []
for u in symbolslist:
t = Thread(target = th, args = (u,))
t.start()
threadlist.append(t)
for b in threadlist:
b.join()
for key, value in dic.items():
print key, value
cur.execute('INSERT INTO Stock(symbol,price) VALUES (?,?)',(key,value))
conn.commit()
cur.close()
我认为错误也许在多线程的部分,因为我可以得到的数据,而无需使用多线程,但在低速。
多线程和这个错误,我只是在最后得到200+(符号,价格),而不是3145
我试图改变DNS和IP,并不能解决问题。
答
我记得我曾遇到多线程和大量套接字打开的问题。额外的锁解决了我的问题。但是,我没有试图找到真正的问题。 urllib doc没有提到有关线程安全的任何信息。你可以尝试这样的事:
global_lock = threading.Lock()
...
def th(ur):
...
with global_lock:
fd = urllib.urlopen(base)
with fd:
htmltext = fd.read()
编辑
你可以使用像(例如)龙卷风或ASYNCIO库选择使用单线程(async IO)代码。
顺便说一句,通过使用每个线程的sqlite连接,您可以在相应的线程中检索到它之后立即存储所刮取的数据。
答
我也有这个错误。我只是为每个线程添加一些睡眠时间,问题就解决了。我用time.sleep(0.1)。
不要使用正则表达式来解析html,还有一个你可以访问的yahoo api,它会给你json –