Python运行脚本后长时间内存分配错误

时间:2016-08-29 11:44:36

标签: python

我有这个用来代码擦除用户名的代码:

def fetch_and_parse_names(url):
    html = requests.get(url).text
    soup = BeautifulSoup(html, "lxml")
    return (a.string for a in soup.findAll(href=USERNAME_PATTERN))

def get_names(urls):
    # Create a concurrent executor
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:

        # Apply the fetch-and-parse function concurrently with executor.map,
        # and join the results together
        return itertools.chain.from_iterable(executor.map(fetch_and_parse_names, urls))

def get_url(region, page):
    return 'http://lolprofile.net/leaderboards/%s/%d' % (region, page)

当它开始将所有名称放在像这样的列表中

urls = [get_url(region, i) for i in range(start, end + 1)]
names = (name.lower() for name in get_names(urls) if is_valid_name(name))

运行一小时后,我得到内存分配错误,显然我知道为什么会发生这种情况,但我该如何解决呢?我想只是从单个页面获取用户名并立即将它们输出到文件,删除列表内容,重复,但我不知道如何实现它。

2 个答案:

答案 0 :(得分:2)

您使用的代码会将所有下载的文档保存在内存中,原因有两个:

  • 您返回a.string,这不只是str而是bs4.element.NavigableString,因此保留对其父级的引用,最终保留对整个文档树的引用。
  • 返回一个生成器表达式,它将捕获本地上下文(在本例中为soup),直到它被使用。

解决此问题的一种方法是使用:

return [str(a.string) for a in soup.findAll(href=USERNAME_PATTERN)]

这样就不会保留对汤对象的引用,并立即执行表达式并返回str列表。

答案 1 :(得分:1)

您可以使用Python Resource Library来增加进程分配的内存,因为进程的线程使用其父进程的内存,但无法分配额外的内存。