当前位置: 首页 > 面试题库 >

与beautifulsoup克隆元素

欧金鹏
2023-03-14
问题内容

我必须将一个文档的一部分复制到另一个文档,但是我不想修改从中复制的文档。

如果使用.extract()它,则从树中删除该元素。如果我只是追加选定的元素,document2.append(document1.tag)它仍然会从document1中删除该元素。

当我使用真实文件时,修改后我无法保存document1,但是有什么方法可以做到而又不会损坏文档?


问题答案:

在4.4版(2015年7月发布)之前的BeautifulSoup中没有本地克隆功能。您必须自己创建一个深层副本,这很棘手,因为每个元素都维护着到树的其余部分的链接。

要克隆一个元素及其所有元素,您必须复制所有属性并 重置 其父子关系。这必须递归地进行。最好通过不复制关系属性并重新安置每个递归克隆的元素来做到这一点:

from bs4 import Tag, NavigableString

def 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, NavigableString


def 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 copy


Tag.clone = tag_clone
NavigableString.clone = lambda self: type(self)(self)

让您.clone()直接调用元素:

document2.body.append(document1.find('div', id_='someid').clone())

我对BeautifulSoup项目的功能请求被接受并进行了调整以使用该copy.copy()功能;
现在,BeautifulSoup 4.4已发布,您可以使用该版本(或更高版本)并执行以下操作:

import copy

document2.body.append(copy.copy(document1.find('div', id_='someid')))


 类似资料:
  • 本文向大家介绍JavaScript浅层克隆与深度克隆示例详解,包括了JavaScript浅层克隆与深度克隆示例详解的使用技巧和注意事项,需要的朋友参考一下 1 相关知识点 浅克隆就是将栈内存中的引用复制一份,赋给一个新的变量,本质上两个指向堆内存中的同一地址,内容也相同,其中一个变化另一个内容也会变化。 深克隆就是创建一个新的空对象,开辟一块内存,然后将原对象中的数据全部复制过去,完全切断两个对象

  • 本文向大家介绍C# 中浅克隆与深克隆(浅拷贝与深拷贝)的区别?相关面试题,主要包含被问及C# 中浅克隆与深克隆(浅拷贝与深拷贝)的区别?时的应答技巧和注意事项,需要的朋友参考一下 (1)浅克隆 在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。简单来说,在

  • 主要内容:示例在某些情况下,您可能需要一个表的完整、精确副本,也即克隆表(复制表)。我们首先想到的是使用 CREATE TABLE 命令创建一张新表,然后使用 SELECT 命令从旧表中选取所有数据,并使用 INSERT 命令插入到新表中。但是这种做法可能达不到您的目的,因为副本必须包含相同的索引、约束、默认值等。 如果您使用 MySQL 数据库,可以借助 SHOW CREATE TABLE 命令,该命令用来展

  • 应用克隆 (用于已有服务,需要在另一个业务线下创建一个同样的服务,不需要重新创建) 服务/环境克隆(菜单栏:工具集->服务/环境克隆) 点击菜单栏,在项目列表中筛选您要克隆的项目,然后点击 克隆 ,弹框中选择您要克隆到哪个业务线。 选择目录空间,系统为在目标空间下生成该应用所需要的所有类型资源和Jenkins Job。

  • HackerNews 克隆是基于 HN 的官方 firebase API 、Vue 2.0 、vue-router 和 vuex 来构建的,使用服务器端渲染。 Live Demo 注:如果在一段时间内没有人访问过该网站,则需要一些加载时间。 [Source] 特性 服务器端渲染 Vue + vue-router + vuex 服务端数据提前获取 客户端状态 & DOM 合并 单文件 Vue 组件

  • void cloneTable(String srcName, String destTable, boolean flushTable) 功能 克隆已存在的表,具有相同的TableSpec和表数据 方法参数 1.srcName : String : required 克隆的源表的表名 2.destTable : String : required 克隆的目标表的表名 3.flushTable :

  • 我们已经按照 ChineseTutorialInstall 安装了 Mercurial,对吗?很好! Mercurial 中,我们在 仓库 里做我们所有的工作。仓库是一个目录,它包含所有我们希望保留历史的源代码和这些源代码的历史记录。 最简单开始 Mercurial 的方法是使用一个已经包含文件和一些历史记录的仓库。 我们使用 clone 命令来做这个事情。 这生产一个仓库的Clone",它生成一

  • 到现在为止,读者已经零略到Git的灵活性以及健壮性。Git可以通过重置随意撤销提交,可以通过变基操作更改历史,可以随意重组提交,还可以通过reflog的记录纠正错误的操作。但是再健壮的版本库设计,也抵挡不了存储介质的崩溃。还有一点就是不要忘了Git版本库是躲在工作区根目录下的.git目录中,如果忘了这一点直接删除工作区,就会把版本库也同时删掉,悲剧就此发生。 “不要把鸡蛋装在一个篮子里”,是颠扑不