我试图在python 2.7.3中使用BeautifulSoup4处理几个网页但是在每次解析之后内存使用量都会上升。
此简化代码产生相同的行为:
from bs4 import BeautifulSoup
def parse():
f = open("index.html", "r")
page = BeautifulSoup(f.read(), "lxml")
f.close()
while True:
parse()
raw_input()
在调用parse()五次之后,python进程已经使用了30 MB的内存(使用的HTML文件大约是100 kB),每次调用它都会增加4 MB。 有没有办法释放内存或某种解决方法?
更新 这种行为让我很头疼。即使BeautifulSoup变量应该被长时间删除,这段代码也会占用大量内存:
from bs4 import BeautifulSoup
import threading, httplib, gc
class pageThread(threading.Thread):
def run(self):
con = httplib.HTTPConnection("stackoverflow.com")
con.request("GET", "/")
res = con.getresponse()
if res.status == 200:
page = BeautifulSoup(res.read(), "lxml")
con.close()
def load():
t = list()
for i in range(5):
t.append(pageThread())
t[i].start()
for thread in t:
thread.join()
while not raw_input("load? "):
gc.collect()
load()
这可能是某种错误吗?
答案 0 :(得分:9)
尝试使用Beautiful Soup的decompose功能,当您使用完每个文件时,它会破坏树。
from bs4 import BeautifulSoup
def parse():
f = open("index.html", "r")
page = BeautifulSoup(f.read(), "lxml")
# page extraction goes here
page.decompose()
f.close()
while True:
parse()
raw_input()
答案 1 :(得分:2)
尝试垃圾收集:
from bs4 import BeautifulSoup
import gc
def parse():
f = open("index.html", "r")
page = BeautifulSoup(f.read(), "lxml")
page = None
gc.collect()
f.close()
while True:
parse()
raw_input()
另见:
答案 2 :(得分:2)
我知道这是一个旧线程,但在使用beautifulsoup解析页面时还要记住一件事。在导航树时,如果要存储特定值,请确保获取字符串而不是bs4对象。例如,当在循环中使用时,这会导致内存泄漏:
category_name = table_data.find('a').contents[0]
可以通过更改为:
来修复category_name = str(table_data.find('a').contents[0])
在第一个示例中,类别名称的类型是bs4.element.NavigableString
答案 3 :(得分:0)
垃圾收集可能是可行的,但上下文管理器似乎很好地处理它,没有任何额外的内存使用:
from bs4 import BeautifulSoup as soup
def parse():
with open('testque.xml') as fh:
page = soup(fh.read())
此外,虽然并非完全必要,但如果您在测试时使用raw_input
让它循环,我实际上发现这个习惯用法非常有用:
while not raw_input():
parse()
每次按下Enter键都会继续循环,但只要输入任何非空字符串,它就会为你停止。