2015-05-22 67 views
0

我想从包含大约4000个页面(每页由25个链接组成)的网站上用Python截取数据。使用Python截取网站数据时的性能问题

我的问题是,经过大约200个处理页面后,性能变得非常可怕,甚至连我的电脑上的其他程序都冻结。

我想这是关于我没有正确使用内存或类似的东西。如果有人能够帮助我解决这个问题,让我的脚本运行更顺利,对我的系统要求更低,我将非常感激。

在此先感谢您的帮助。 :)

编辑: 我发现你可以找到它,当你向下滚动了一下,我给的答案的解决方案。感谢所有试图帮助我的人,特别是etna和Walter A,他们给我提供了很好的建议,帮助我走上正轨。 :)

from pprint import pprint 
from lxml import etree 
import itertools 
import requests 

def function parsePageUrls(page): 
    return page.xpath('//span[@class="tip"]/a/@href') 

def function isLastPage(page): 
    if not page.xpath('//a[@rel="next"]'): 
     return True 

urls = [] 
for i in itertools.count(1): 
    content = requests.get('http://www.example.com/index.php?page=' + str(i), allow_redirects=False) 
    page = etree.HTML(content.text) 

    urls.extend(parsePageUrls(page)) 

    if isLastPage(page): 
     break 

pprint urls 
+0

我可以告诉你的是我知道我做了一个request.get需要2-4秒。我会尝试在for循环结尾添加一个time.sleep(3)(左右)。这将需要更长的时间,但我敢打赌它不会崩溃。值得一试。 –

+0

如果你说了你正在使用的操作系统,以及你拥有的CPU和RAM的数量,这将有所帮助。 –

+0

通常会出现这样的内存问题,因为您存储的对象不是简单的字符串,而是引用树的内容,因此会导致每个树在内存中保持活动状态,即使您希望它在循环中被覆盖, 。 – etna

回答

0

我终于找到了解决方案。问题是我认为我使用了一个字符串列表作为tree.xpath的返回值,但是它是一个_ElementUnicodeResult对象的列表,它阻止GC清除内存,因为它们持有对其父项的引用。

因此,解决方案是将这些_ElementUnicodeResult对象转换为普通字符串以摆脱引用。

这里是源,帮助我走出认识问题:http://lxml.de/api/lxml.etree._ElementTree-class.html#xpath

至于所提供的代码下面固定它:

相反的:

urls.extend(parsePageUrls(page)) 

它必须是:

for url in parsePageUrls(page): 
    urls.append(str(url))