在4.4版(2015年7月发布)之前的BeautifulSoup中没有本地克隆功能。您必须自己创建一个深层副本,这很棘手,因为每个元素都维护着到树的其余部分的链接。
要克隆一个元素及其所有元素,您必须复制所有属性并 重置 其父子关系。这必须递归地进行。最好通过不复制关系属性并重新安置每个递归克隆的元素来做到这一点:
from bs4 import Tag, NavigableStringdef clone(el): if isinstance(el, NavigableString): return type(el)(el) copy = Tag(None, el.builder, el.name, el.namespace, el.nsprefix) # work around bug where there is no builder set # https://bugs.launchpad.net/beautifulsoup/+bug/1307471 copy.attrs = dict(el.attrs) for attr in ('can_be_empty_element', 'hidden'): setattr(copy, attr, getattr(el, attr)) for child in el.contents: copy.append(clone(child)) return copy该方法对当前的BeautifulSoup版本敏感。我使用4.3进行了测试,将来的版本可能还会添加需要复制的属性。
您也可以将此功能猴子修补到BeautifulSoup中:
from bs4 import Tag, NavigableStringdef tag_clone(self): copy = type(self)(None, self.builder, self.name, self.namespace, self.nsprefix) # work around bug where there is no builder set # https://bugs.launchpad.net/beautifulsoup/+bug/1307471 copy.attrs = dict(self.attrs) for attr in ('can_be_empty_element', 'hidden'): setattr(copy, attr, getattr(self, attr)) for child in self.contents: copy.append(child.clone()) return copyTag.clone = tag_cloneNavigableString.clone = lambda self: type(self)(self)让您
.clone()直接调用元素:
document2.body.append(document1.find('div', id_='someid').clone())我对BeautifulSoup项目的功能请求被接受并进行了调整以使用该
copy.copy()功能;
现在,BeautifulSoup 4.4已发布,您可以使用该版本(或更高版本)并执行以下操作:
import copydocument2.body.append(copy.copy(document1.find('div', id_='someid')))


