我知道过去曾问过这个问题,但是我仍然很困惑,如果可能的话,我想一劳永逸地解决我的疑问。
如果我使用
from bs4 import BeautifulSoup
我的soup
任务将会
soup = BeautifulSoup(html, "lxml")
如果我这样导入:
from bs4 import BeautifulSoup as bs4
我的soup
分配是
soup = bs4(html, "lxml")
最后,如果我使用以下命令导入
:import bs4
我的soup
分配是
soup = bs4.BeautifulSoup(html, "lxml")
让我们使用简单的html和代码:
html = """
<a href="some link" style="some style">Some Document</a>
"""
link = soup.select('a:contains(Document)')
接下来,主要问题:
type(link[0])
在所有三种导入情况下,输出为:
bs4.element.Tag
但是,如果我问:
isinstance(link[0],bs4.element.Tag)
在第三种情况下,我得到True
,但在前两种情况下,我得到
AttributeError: type object 'BeautifulSoup' has no attribute 'element'
由于select()
和find_all()
方法经常传递Tag
或NavigableString
结果,因此我需要使用isinstance()
确定哪个是哪个。因此,在这些情况下,我必须使用第三种导入方法吗?为什么首先要有区别?
答案 0 :(得分:1)
这是您正在做的命名游戏。让我们继续说一下,类bs4.element.Tag
是元素实例的类。可以将其视为Tag
中bs4
类的绝对位置。 bs4.element
代表嵌套的模块,其中Tag
(在element
模块下)是元素作为其实例的类。显示这些元素的类信息时,它将始终显示bs4.element.Tag
。
现在,如上所述,您可以通过不同的方式访问BeautifulSoup
对象。这一切都不会改变元素标记为bs4.element.Tag
类型的事实。导入bs4时:
import bs4
bs4.BeautifulSoup()
这将以模块的默认名称bs4
导入模块。然后,您可以使用点标记访问该模块中的BeautifulSoup
,因为BeautifulSoup
是该模块的成员。但是本地bs4
只是引用bs4
模块的变量。
当您导入为:
from bs4 import BeautifulSoup as bs4
bs4
与第一个示例的含义不同。在第一个示例中,我们以其默认名称(bs4
)导入了整个模块,但是在这里,我们导入了BeautifulSoup
类,并在本地将其重命名为bs4
。无论我们在本地如何称呼它,它仍然是bs4.BeautifulSoup
的类,其中bs4
是模块名称。不过,在本地(此文件本地),我们创建了一个指向BeautifulSoup
类的变量引用,其名称恰好与模块相同。
因此,当您使用select
返回元素时,它们的类型为bs4.element.Tag
。无论您的本地变量碰巧被命名为什么,这都是正确的。这是内部的知名度。
因此,在比较instance
时,重要的是要知道,变量名称并不重要,重要的是变量所引用的内容。在第三个示例中,import bs4
导致bs4
引用bs4
模块;因此,可以从Tag
访问bs4.element.Tag
。但是,在使用from bs4 import BeautifulSoup as bs4
的情况下,bs4
不再引用bs4
模块,它引用的BeautifulSoup
类没有名为element
的属性,属性Tag
,因为它不是模块而是类。
本地名称就是您当前文件引用它所引用的对象的方式。
因此,在失败的情况下,您需要将Tag
引用导入可以提供给instance
的变量:
>>> from bs4 import BeautifulSoup
>>> from bs4.element import Tag
>>> soup = bs4.BeautifulSoup('<div>Test<span>test</span><span>test2</span></div>')
>>> isinstance(soup.find('div'), Tag)
True
Tag
只是一个名称,但它引用了bs4.element.Tag
,因此可以使用。
我们可以称之为任何东西,只要它引用了正确的对象,它就仍然可以工作:
>>> from bs4 import BeautifulSoup
>>> from bs4.element import Tag as Apple
>>> soup = bs4.BeautifulSoup('<div>Test<span>test</span><span>test2</span></div>')
>>> isinstance(soup.find('div'), Apple)
True
希望这更有意义:)。
编辑:只是一个提示,但是bs4
对顶层模块中可用的NavigableString
和Tag
之类的内容进行了一些引用,因此您不必一路走来到bs4.element
以获得正确的参考,您只需执行以下操作:
from bs4 import Tag, NavigableString
同样,bs4.Tag
的替代引用只是Tag
模块中名为bs4
的变量,它引用实际的bs4.element.Tag
类。您可以使用它,它仍将引用同一类。只是在bs4
模块中本地使用它来引用Tag
中的element
类。