python – 超出最大递归深度.多处理和bs4
我正在尝试使解析器使用beautifulSoup和多处理.我有一个错误:
我的代码是: import bs4,requests,time from multiprocessing.pool import Pool html = requests.get('https://www.avito.ru/moskva/avtomobili/bmw/x6?sgtd=5&radius=0') soup = bs4.BeautifulSoup(html.text,"html.parser") divList = soup.find_all("div",{'class': 'item_table-header'}) def new_check(): with Pool() as pool: pool.map(get_info,divList) def get_info(each): pass if __name__ == '__main__': new_check() 为什么我会收到此错误以及如何解决? 更新: Traceback (most recent call last): File "C:/Users/eugen/PycharmProjects/avito/main.py",line 73,in <module> new_check() File "C:/Users/eugen/PycharmProjects/avito/main.py",line 67,in new_check pool.map(get_info,divList) File "C:UserseugenAppDataLocalProgramsPythonPython36libmultiprocessingpool.py",line 266,in map return self._map_async(func,iterable,mapstar,chunksize).get() File "C:UserseugenAppDataLocalProgramsPythonPython36libmultiprocessingpool.py",line 644,in get raise self._value File "C:UserseugenAppDataLocalProgramsPythonPython36libmultiprocessingpool.py",line 424,in _handle_tasks put(task) File "C:UserseugenAppDataLocalProgramsPythonPython36libmultiprocessingconnection.py",line 206,in send self._send_bytes(_ForkingPickler.dumps(obj)) File "C:UserseugenAppDataLocalProgramsPythonPython36libmultiprocessingreduction.py",line 51,in dumps cls(buf,protocol).dump(obj) RecursionError: maximum recursion depth exceeded 解决方法
使用多处理时,传递给worker的所有内容都必须为
pickled.
不幸的是,很多BeautifulSoup树都无法腌制. 这有几个不同的原因.其中一些是已修复的错误,所以你可以尝试确保你有最新的bs4版本,有些是特定于不同的解析器或树构建器……但是这样的事情很有可能对这有帮助. 但根本问题是树中的许多元素都包含对树的其余部分的引用. 偶尔,这会导致实际的无限循环,因为循环引用对于其循环引用检测来说太间接.但这通常是一个被修复的错误. 但是,更重要的是,即使循环不是无限的,它仍然可以拖动来自树的其余部分的1000多个元素,这已经足以导致RecursionError. 我认为后者就是这里发生的事情.如果我拿你的代码并尝试挑选divList [0],它就会失败. (如果我将递归限制上升并计算帧数,它需要23080的深度,这是超过默认值1000的方式.)但是,如果我采用完全相同的div并分别解析它,它成功没有问题. 所以,一种可能性是只做sys.setrecursionlimit(25000).这将解决这个确切页面的问题,但稍微不同的页面可能需要甚至更多. (另外,设置递归限制通常不是一个好主意,因为浪费的内存不是很多,而是因为它意味着实际的无限递归需要25倍的时间和25倍的浪费资源来检测.) 另一个技巧是编写“修剪树”的代码,在你腌制它之前消除div中的任何向上链接.这是一个很好的解决方案,除了它可能需要做很多工作,并且需要深入了解BeautifulSoup如何工作的内部,我怀疑你想做什么. 最简单的解决方法是有点笨重,但是……你可以将汤转换为字符串,将其传递给孩子,并让孩子重新解析它: def new_check(): divTexts = [str(div) for div in divList] with Pool() as pool: pool.map(get_info,divTexts) def get_info(each): div = BeautifulSoup(each,'html.parser') if __name__ == '__main__': new_check() 这样做的性能成本可能并不重要;更大的担心是,如果你有不完美的HTML,转换为字符串并重新解析它可能不是一个完美的往返.因此,我建议您先进行一些测试,不要先进行多处理,以确保不影响结果. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- python-Cython函数指针取消引用时间(与直接调用函数相比)
- python – dict.setdefault(key,[]).append() – >去除附加
- 【Python】【并行计算】Python 多核并行计算
- python – 如何从github pip安装… powershell给出错误找不
- 在Python 3中不使用`break`来停止迭代
- python – Django REST自定义错误
- selenium-find_element相关内容(2)
- Python中文编码那些事
- Python:用迭代器和生成器降低程序内存占用率
- python-2.7 – 来自oracle数据库的大数据的内存管理