我制作了一个简单的网络爬虫程序,使用urllib和beautifulsoup从网页上的表中提取数据。为了加快数据拉取速度,我尝试使用线程,但出现以下错误: “内部缓冲区错误:内存分配失败:缓冲区增长” 此消息出现多次,然后声明: “内存不足”
谢谢你的帮助。在
from bs4 import BeautifulSoup
from datetime import datetime
import urllib2
import re
from threading import Thread
stockData = []
#Access the list of stocks to search for data
symbolfile = open("stocks.txt")
symbolslist = symbolfile.read()
newsymbolslist = symbolslist.split("\n")
#text file stock data is stored in
myfile = open("webcrawldata.txt","a")
#initializing data for extraction of web data
lineOfData = ""
i=0
def th(ur):
stockData = []
lineOfData = ""
dataline = ""
stats = ""
page = ""
soup = ""
i=0
#creates a timestamp for when program was won
timestamp = datetime.now()
#Get Data ONLINE
#bloomberg stock quotes
url= "http://www.bloomberg.com/quote/" + ur + ":US"
page = urllib2.urlopen(url)
soup = BeautifulSoup(page.read())
#Extract key stats table only
stats = soup.find("table", {"class": "key_stat_data" })
#iteration for <tr>
j = 0
try:
for row in stats.findAll('tr'):
stockData.append(row.find('td'))
j += 1
except AttributeError:
print "Table handling error in HTML"
k=0
for cell in stockData:
#clean up text
dataline = stockData[k]
lineOfData = lineOfData + " " + str(dataline)
k += 1
g = str(timestamp) + " " + str(ur)+ ' ' + str(lineOfData) + ' ' + ("\n\n\n")
myfile.write(g)
print (ur + "\n")
del stockData[:]
lineOfData = ""
dataline = ""
stats = None
page = None
soup = None
i += 1
threadlist = []
for u in newsymbolslist:
t = Thread(target = th, args = (u,))
t.start()
threadlist.append(t)
for b in threadlist:
b.join()enter code here
您启动的每个线程都有一个线程堆栈大小,即8KB Linux系统中的默认值(请参见
ulimit -s
),因此线程所需的内存总量将超过20 GB。在您可以使用一个线程池,例如10个线程;当一个 它已经完成了它的工作,它还有另一个任务要做。在
但是:一般来说,运行比CPU核心更多的线程是无稽之谈。所以我的 建议停止使用线程。您可以使用gevent这样的库来 在不使用操作系统级线程的情况下执行完全相同的操作。在
gevent的好处是猴子修补:你可以分辨出gevent 为了改变Python标准库的行为,这将使 透明地进入“greenlet”对象(参见gevent文档 更多细节)。gevent提出的并发类型是 特别适合于密集的I/O。在
在代码中,只需在开头添加以下内容:
上不能同时打开超过1024个文件描述符 默认情况下是Linux系统(请参见
ulimit -n
),因此您必须增加 如果您希望同时打开2700个文件描述符,则可以使用此限制。在不要重新发明轮子并使用^{} web-scraping framework :
想想看-可伸缩性/并行化/性能问题已经为您解决了-您真的想继续深入到python中的
Thread
的奇妙世界,让您的代码变得可疑,达到CPU和内存限制,处理冲突,并最终使您的代码无法调试和维护吗-而不是专注于提取和收集数据?而且,即使使用gevent
,我也怀疑您的最终代码是否会比基于Scrapy实现的代码更简单易读。为什么不使用这个已经被大量用户测试和使用的工具,它被证明是在web抓取python世界中创建的最好的工具呢?在下面是一个工作的蜘蛛,它以类似的方式抓取引号:
如果
^{pr2}$stocks.txt
的内容是:spider将输出(例如,如果选择以JSON格式输出):
一个很好的地方开始与瘙痒是Scrapy Tutorial。在
相关问题 更多 >
编程相关推荐