Когда вы используете multiprocessing
, все, что вы передаете работнику, должно быть засолено .
К сожалению, многие BeautifulSoup
деревья не могут быть засолены.
Для этого есть несколько причин.Некоторые из них являются ошибками, которые с тех пор были исправлены, поэтому вы могли бы попробовать убедиться, что у вас установлена последняя версия bs4, а некоторые относятся к разным парсерам или построителям деревьев ... но есть хороший шанс, что ничего подобного не произойдетhelp.
Но фундаментальная проблема заключается в том, что многие элементы в дереве содержат ссылки на остальную часть дерева.
Иногда это приводит к фактическому бесконечному циклу, поскольку круговые ссылки слишкомкосвенный для его обнаружения круговой ссылки.Но обычно это ошибка, которая исправляется.
Но, что еще более важно, даже когда цикл не является бесконечным , он все равно может тянуть более 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, преобразование в строку и повторный разбор не могли бы быть идеальным циклом.Поэтому я бы посоветовал вам сначала выполнить несколько тестов без многопроцессорной обработки, чтобы убедиться, что это не повлияет на результаты.