我代表所有者从新闻网站上抓文章。我必须保持每秒<= 5次请求,或者6小时内(晚上)约10万篇文章,但我最多只能获得~30k。
使用Jupyter笔记本,它首先运行良好,但反应越来越少。 6小时后,内核通常是不可中断的,我必须重新启动它。由于我将每篇文章存储在内存中,这是一个问题。
所以我的问题是:有没有更有效的方法来在6小时内达到~100k文章?
代码如下。对于Pandas数据帧列中的每个有效URL,循环:
我考虑过的一些想法:
删除所有&#34; print()&#34;功能,并完全依赖于日志记录(我的记录器配置似乎没有表现出色,但是 - 我不确定它是否记录了我告诉它的所有内容)
timer_table = {1, 22, 6, 3, 100, 2}
这是我正在使用的日志配置。我在SO上发现了它,但是这个特殊的脚本它似乎并不能捕获所有东西。
i=0
#lots of NaNs in the column, hence the subsetting
for u in unique_urls[unique_urls['unique_suffixes'].isnull() == False]\
.unique_suffixes.values[:]:
i = i+1
if pd.isnull(u):
continue
#save our progress every 2k articles just in case
if i%2000 == 0:
unique_urls.to_csv('/backup-article-txt.csv', encoding='utf-8')
try:
#pull the data
html_r = requests.get(u).text
#the phrase "TX:" indicates start of article
#text, so if it's not present, URL must have been bad
if html_r.find("TX:") == -1:
continue
#capture just the text of the article
txt = html_r[html_r.find("TX:")+5:]
#fix encoding/formatting quirks
txt = txt.replace('\n',' ')
txt = txt.replace('[^\x00-\x7F]','')
#wait 200 ms to spare site's servers
time.sleep(.2)
#write our article to our dataframe
unique_urls.loc[unique_urls.unique_suffixes == u, 'article_text'] = txt
logging.info("done with url # %s -- %s remaining", i, (total_links-i))
print "done with url # " + str(i)
print total_links-i
except:
logging.exception("Exception on article # %s, URL: %s", i, u)
print "ERROR with url # " + str(i)
continue
eta:回答/评论的一些细节:
脚本只能在16 GB / ram EC2实例上运行
文章每篇约100-800字
答案 0 :(得分:1)
根据你的描述,我将采取一种有根据的猜测并说你的脚本将你的机器变成一个交换风暴,因为你得到了大约30k的文章。我在代码中看不到任何可以使用以下内容轻松释放内存的内容:
some_large_container = None
设置你知道的对None
有大量分配的东西告诉Python的内存管理器它可用于垃圾收集。你也可能想要明确地调用gc.collect()
,但我不确定那对你有多好处。
您可以考虑的替代方案:
sqlite3
:使用sqlite3
作为中间存储,而不是远程SQL数据库。存在一个Python模块。zlib.compress()
压缩字符串。你决定去的任何方式,你可能最好将收集作为第1阶段,将Pandas数据框架构建为第2阶段。永远不要为了聪明一半而付出代价。另一半往往会挂你。