首页 > 其他分享 >爬虫之BeautifulSoup四大对象

爬虫之BeautifulSoup四大对象

时间:2024-03-31 21:12:39浏览次数:35  
标签:对象 标签 BeautifulSoup 爬虫 soup tag 四大 属性

一、四大对象种类

1、简介

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:

对象名 描述
BeautifulSoup 文档自身:表示的是一个文档的全部内容
Tag 标签对:Tag对象与XML或HTML原生文档中的tag相同,即标签对
NavigableString 标签值:标签对中的字符串
Comment 注释:文档的注释部分
  1. Tag(标签):Tag对象表示HTML或XML文档中的标签,它包含了标签的名称、属性和内容。您可以通过Tag对象访问标签的属性和内容,以及对标签进行操作和修改。

  2. NavigableString(可导航字符串):NavigableString对象表示标签内的文本内容,它是标签内文本的容器。您可以通过NavigableString对象访问文本内容,进行文本处理和操作。

  3. BeautifulSoup(Beautiful Soup对象):BeautifulSoup对象表示整个文档,它是文档的顶层容器,包含了整个文档的结构信息。您可以通过BeautifulSoup对象来遍历文档树、搜索元素以及提取数据。

  4. Comment(注释):Comment对象表示文档中的注释内容,它用于表示HTML或XML文档中的注释部分。您可以通过Comment对象访问注释内容。

这些对象的组合和结构构成了Beautiful Soup库对文档的解析表示,使用户能够方便地操作和提取文档中的数据。在使用Beautiful Soup进行网页数据提取和处理时,您将会频繁地与这些对象打交道。

2、详细介绍

以下是它们的详细介绍以及附带的代码解释:

(1)BeautifulSoup(Beautiful Soup对象)

  • BeautifulSoup对象表示整个文档,是文档的顶层容器,包含了整个文档的结构信息。
  • 您可以通过BeautifulSoup对象来遍历文档树、搜索元素以及提取数据。
# 示例代码
from bs4 import BeautifulSoup

# 创建一个简单的HTML文档
html_doc = "<html><body><p>Welcome to Beautiful Soup</p></body></html>"

# 使用BeautifulSoup解析HTML文档
soup = BeautifulSoup(html_doc, 'html.parser')

# 打印整个文档
print(soup.prettify())

(2)Tag(标签)

  • Tag对象代表HTML或XML文档中的标签,包含标签的名称、属性和内容。
  • 在BeautifulSoup中可以利用beautifulsoup对象下面的方法返回这些标签数据,这些标签数据称为Tag对象(Tag对象指的是整个标签对:从开始标签到结束标签,包括里面的嵌套标签)

① 获取Tag对象

从一个beautifulsoup对象中获取指定的Tag对象,可以使用:beautifulsoup对象.标签名

注:这种方法返回的Tag对象是所有内容中第一个符合要求的标签
即:文档中存在多个同名的标签时,使用"beautifulsoup对象.标签名"返回的始终是第一个符合的标签

示例

from bs4 import BeautifulSoup  # 导入bs4库
 
htmlData = """
<html>
 <head> 
    <title>The Dormouse's story</title> 
 </head> 
 <body> 
  <p class="title"><b>The Dormouse's story</b></p> 
  <p class="story">
    <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
    <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
    <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
  </p> 
  <p class="story">they lived at the bottom of a well</p> 
 </body>
</html>
"""
 
soup = BeautifulSoup(htmlData, "lxml")
 
# 获取head标签
headTag = soup.head
print("获取到的heade标签为:", headTag)
# 获取title标签
titleTag = soup.title
print("获取到的title标签为:", titleTag)
# 获取a标签
aTag = soup.a
print("获取到的a标签为:", aTag)
# 获取p标签
pTag = soup.p
print("获取到的p标签为:", pTag)
print("获取到的p标签类型为:", type(pTag))
 
"""
获取到的header标签为: <head>
<title>The Dormouse's story</title>
</head>
获取到的title标签为: <title>The Dormouse's story</title>
获取到的a标签为: <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
获取到的p标签为: <p class="title"><b>The Dormouse's story</b></p>
获取到的p标签类型为: <class 'bs4.element.Tag'>
"""

② tag对象的name属性

  • 每个tag都有自己的名字,其成为tag对象的name属性(name属性:标签对的名称)

  • 获取一个Tag对象的name属性,可以使用:Tag对象.name

示例

from bs4 import BeautifulSoup #导入bs4库
 
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
 
soup = BeautifulSoup(html,"lxml")   #指定解析器
soup_tag_name = soup.name    #获取整个BeautifulSoup对象的name属性
title_tag_name = soup.title.name  #获取title标签对象的name属性
head_tag_name = soup.head.name  #获取head标签对象的name属性
a_tag = soup.a    #获取a标签对象
a_tag_name = a_tag.name #获取a标签对象的name属性
 
print("整个BeautifulSoup对象的name属性为:",soup_tag_name)
print("title标签对象的name属性为:",title_tag_name)
print("header标签对象的name属性为:",head_tag_name)
print("a标签对象为:",a_tag)
print("a标签对象的name属性为:",a_tag_name)
 
"""
整个BeautifulSoup对象的name属性为: [document]
title标签对象的name属性为: title
header标签对象的name属性为: head
a标签对象为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
a标签对象的name属性为: a
"""

③ tag对象的attrs属性

  • attrs属性:指的是一个标签的属性

    • 一个标签的属性一般是由键值对组成,属性名=值
    • <p class="story">...</p>,其中的class="story"就是标签的属性
  • 一个标签可能有很多个属性

  • 获取一个Tag对象的attrs属性,可以使用:Tag对象.attrs

  • 使用Tag对象的attrs属性可以把标签对的属性以字典形式返回

    • Tag对象无属性时返回的是一个空字典

示例

from bs4 import BeautifulSoup #导入bs4库
 
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
 
soup = BeautifulSoup(html,"lxml")   #指定解析器
soup_tag_attrs = soup.attrs #获取整个BeautifulSoup对象的attrs属性
title_tag_attrs = soup.title.attrs #获取title Tag对象的attrs属性
head_tag_attrs = soup.head.attrs #获取head Tag对象的attrs属性
a_tag = soup.a      #获取a标签的Tag对象
a_tag_attrs = a_tag.attrs   #获取a Tag对象的attrs属性
 
 
print("BeautifulSoup对象的attrs属性为:",soup_tag_attrs)
print("titlea标签的Tag对象的attrs属性为:",title_tag_attrs)
print("heada标签的Tag对象的attrs属性为:",head_tag_attrs)
print("a标签的Tag对象为:",a_tag)
print("a标签的Tag对象的attrs属性为:",a_tag_attrs)
 
"""
BeautifulSoup对象的attrs属性为: {}
titlea标签的Tag对象的attrs属性为: {}
heada标签的Tag对象的attrs属性为: {}
a标签的Tag对象为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
a标签的Tag对象的attrs属性为: {'id': 'link1', 'href': 'http://example.com/elsie', 'class': ['sister']}
"""

如果想要单独获取某个属性具体的值时,可以使用下面三种方法:
(1)使用字典方法:字典索引、字典get()方法
(2)使用tag对象的get()方法:soup对象.标签名.get(属性名)
(3)使用soup对象.标签名.属性名(键名)

④ 多值属性

  • 一般情况下,对于标签的属性都是以键值对存在的(一键一值,键=值)。但是某些属性可以存在多个值的情况(一键多值)。这种情况就称为多值属性

  • 最常见的多值的属性是 class (一个tag可以有多个CSS的class)。还有一些属性rel , rev , accept-charset , headers , accesskey。在Beautiful Soup中多值属性的返回类型是列表

from bs4 import BeautifulSoup
 
soup = BeautifulSoup('<p class="body strikeout"></p>',"lxml")
 
print("p标签的tag对象为",soup.p)
 
print("p标签的tag对象的属性为",soup.p.attrs)  #其值为一个字典
print("p标签的class属性为",soup.p.attrs.get("class"))
 
 
css_soup = BeautifulSoup('<p class="body"></p>',"lxml")
print(css_soup.p['class'])
 
"""
p标签的tag对象为 <p class="body strikeout"></p>
p标签的tag对象的属性为 {'class': ['body', 'strikeout']}
p标签的class属性为 ['body', 'strikeout']
['body']
"""

特别注意之处

from bs4 import BeautifulSoup
 
# 如果某个属性看起来好像有多个值,但在任何版本的HTML定义中都没有被定义为多值属性,那么Beautiful Soup会将这个属性作为字符串返回
css_soup = BeautifulSoup('<p id="my id"></p>',"lxml")
print(css_soup.p['id'])  # id是一对第一,并非多值属性
  
#如果转换的文档是XML格式,那么tag中不包含多值属性
xml_soup = BeautifulSoup('<p class="body strikeout"></p>', 'xml')
print(xml_soup.p['class'])
 
"""
my id
body strikeout
"""

⑤ 获取标签对象的文本内容

在Beautiful Soup中,.string.strings是用于获取标签对象文本内容的两个不同属性或方法。

  1. .string

    • .string是用于获取标签对象中的单个字符串内容的属性。如果标签对象只包含单个字符串,那么使用.string可以直接获取这个字符串内容。
    • 如果标签对象包含多个字符串,但这些字符串之间没有标签或其他元素分隔,.string会返回这些字符串合并后的内容。
    • 如果标签对象包含子标签,.string会返回None,因为这种情况下标签对象不是单个字符串。
  2. .strings

    • .strings是用于获取标签对象中所有字符串内容的生成器(generator)方法。它会返回一个生成器对象,可以用于迭代获取标签对象中的所有字符串内容。
    • 如果标签对象包含多个字符串,.strings会将这些字符串分别作为独立的元素返回。
    • 如果标签对象包含子标签,.strings会忽略子标签,只返回直系子元素中的字符串内容。

下面是一个示例代码,演示了.string.strings的用法:

from bs4 import BeautifulSoup

# 创建一个包含多个字符串的标签对象
html_doc = "<html><body><p>Welcome to <b>Beautiful Soup</b></p></body></html>"
soup = BeautifulSoup(html_doc, 'html.parser')

# 使用.string获取单个字符串内容
p_tag = soup.find('p')
single_string = p_tag.string
print(single_string)

# 使用.strings获取所有字符串内容
all_strings = list(p_tag.strings)
print(all_strings)

# None
# ['Welcome to ', 'Beautiful Soup']

在这个示例中,我们首先创建了一个包含多个字符串的标签对象。然后,我们分别使用.string.strings来获取其中的字符串内容。.string返回了标签对象中的单个字符串内容,而.strings返回了所有字符串内容的生成器对象。

(3)NavigableString(可导航字符串)

  • NavigableString对象表示标签内的文本内容,是标签内文本的容器。
  • 您可以通过NavigableString对象访问文本内容,进行文本处理和操作。
# 示例代码
from bs4 import BeautifulSoup

# 创建一个简单的HTML文档
html_doc = "<html><body><p>Welcome to <strong>Beautiful Soup</strong></p></body></html>"

# 使用BeautifulSoup解析HTML文档
soup = BeautifulSoup(html_doc, 'html.parser')

# 获取<p>标签内的文本
p_tag = soup.find('p')
text_content = p_tag.string

# 打印文本内容
print(text_content)  # 输出:'Welcome to '

# 修改文本内容
text_content.replace_with('Welcome to the Beautiful Soup Library')

# 打印修改后的文本内容
print(p_tag.text)  # 输出:'Welcome to the Beautiful Soup Library'

(4)Comment(注释)

  • Comment对象表示文档中的注释内容,用于表示HTML或XML文档中的注释部分。
  • 您可以通过Comment对象访问注释内容。
# 示例代码
from bs4 import BeautifulSoup

# 创建一个包含注释的HTML文档
html_doc = "<html><body><!-- This is a comment --><p>Welcome to Beautiful Soup</p></body></html>"

# 使用BeautifulSoup解析HTML文档
soup = BeautifulSoup(html_doc, 'html.parser')

# 获取注释内容
comment = soup.body.contents[0]

# 打印注释内容
print(comment)  # 输出:' This is a comment '

二、补充

1、获取Tag对象

获取某个指定的tag有两种情况:一种是获取指定的第一个标签(这种实际中用得很少),另一种是获取指定的全部标签对

(1)获取指定的第一个标签

获取指定的第一个标签就是使用前面介绍的"soup对象.标签名"

示例:soup对象.标签名

from bs4 import BeautifulSoup
 
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
 
soup = BeautifulSoup(html,"lxml")#一个<class 'bs4.BeautifulSoup'>
 
tag_p = soup.p
print("p标签对为:",tag_p)
 
tag_a = soup.a
print("a标签对为:",tag_a)
 
"""
p标签对为: <p class="title" name="dromouse"><b>The Dormouse's story</b></p>
a标签对为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
"""

(2)获取指定的全部标签对

要获取一个文档中某个指定的所有标签,就需要使用find_all()方法BeautifulSoup对象或Tag对象都可以使用find_all()或find()方法来找其下面的子标签(只是查找范围不一样:BeautifulSoup对象->整个xml对象内,Tag对象->该Tag对象内)

其参数可以是很多类型,最常用的是:传入需要获取的标签的标签名

find_all()方法返回的是一个由所有符合要求的标签组成的列表

个人建议:不管HTML或XML文档中有无重复的标签,都最好用find_all()方法来找对应的Tag对象。

示例:find_all()

from bs4 import BeautifulSoup
 
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
 
soup = BeautifulSoup(html,"lxml")
 
tag_body = soup.find_all("p") #获取所有p标签的tag对象
print("p标签对为:",tag_body)
 
tag_a = soup.find_all("a")    #获取所有a标签的tag对象
print("a标签对为:",tag_a)
 
"""
p标签对为: [<p class="title" name="dromouse"><b>The Dormouse's story</b></p>, <p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>, <p class="story">...</p>]
a标签对为: [<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
"""

ps:

  1. find_all()方法用于返回整个文档中所有符合要求的标签对:返回值是由所有符合要求的tag对象组成的列表(遍历后就是一个个tsg对象)。

  2. 同样的方法还有find()方法:只是find()方法只是返回第一个符合要求的标签对。

  3. 使用这种方法的话,就可以将标签名定义成变量,方便后续使用。

2、tag对象的name和attrs属性

自己理解的解析过程就是:soup对象->Tag对象->通过tag对象的name、attrs和另外的string属性来获取想要的数据

使用这种方法的话也是:只会返回第一个符合要求的标签名的name和attrs(因为返回的只有一个tag对象)

标签对的attrs属性返回值是一个字典,可以对其使用字典的方法

tag的属性可以被添加,删除或修改,与字典处理方法一致,如:tag['class'] = 'verybold'

# 修改第一个a标签的 class 属性值
soup.a["class"] = ["sister c1"]
# 删除第一个a标签的id属性值
del soup.a["id"]
print(soup)
# 可以发现第一个a标签的id属性值被删除了

完整示例

from bs4 import BeautifulSoup
 
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
 
soup = BeautifulSoup(html,"lxml")
 
def parse_msg(tagName):
    tags = soup.find_all(tagName) #find_all()返回的是一个由tag对象组成的列表,因此需要遍历
    for tag in tags:
        print("标签的tag对象为为:", tag)
        print("标签的名称为:",tag.name)
        print("标签的属性为:",tag.attrs)
        print("标签的数据为:", tag.string)
 
parse_msg("a")
parse_msg("p")
 
 
"""
标签的tag对象为为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
标签的名称为: a
标签的属性为: {'class': ['sister'], 'href': 'http://example.com/elsie', 'id': 'link1'}
标签的数据为:  Elsie 
标签的tag对象为为: <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
标签的名称为: a
标签的属性为: {'class': ['sister'], 'href': 'http://example.com/lacie', 'id': 'link2'}
标签的数据为: Lacie
标签的tag对象为为: <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
标签的名称为: a
标签的属性为: {'class': ['sister'], 'href': 'http://example.com/tillie', 'id': 'link3'}
标签的数据为: Tillie
标签的tag对象为为: <p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
标签的名称为: p
标签的属性为: {'class': ['story']}
标签的数据为: None
标签的tag对象为为: <p class="story">...</p>
标签的名称为: p
标签的属性为: {'class': ['story']}
标签的数据为: ...
"""
  1. 上面的流程就是:先使用find_all()方法获取所有符合要求的tag对象组成的列表,然后遍历出每一个tag对象,最后获得每一个tag对象的name、attrs属性以及string

  2. 也可以使用soup.标签名["属性名"]来获取指定名字的attrs属性

  3. 这种嵌套在里面的标签对,如果返回的是外层的tag对象,那也只能获得外层tag对象的name和attrs属性

标签:对象,标签,BeautifulSoup,爬虫,soup,tag,四大,属性
From: https://www.cnblogs.com/xiao01/p/18104295

相关文章

  • 爬虫之BeautifulSoup文档树操作
    一、遍历文档树介绍1、简介在BeautifulSoup中,遍历文档树是指访问和操作HTML或XML文档的各个部分,包括标签、字符串内容等。遍历文档树,也被称为导航文档树,是指在一个文档对象模型(DOM)中按照特定的方法和规则来遍历和浏览其中的节点。DOM是一种处理XML或HTML文档的标准编程接口,......
  • 抖音视频无水印批量下载软件|视频关键词爬虫提取工具
    抖音视频无水印批量下载软件,轻松获取你想要的视频内容!    想要快速获取抖音上的视频内容吗?现在推出的抖音视频无水印批量下载软件将帮助你实现这一愿望!主要功能包括关键词批量提取视频和单独视频提取,让你轻松下载喜欢的视频内容。主要功能解析:1.关键词批量提取视频......
  • 八股文——TCP四大机制!小白也能懂!(重传机制、滑动窗口、流量控制、拥塞控制)
    引言TCP巨复杂!同时在八股计算机网络中也经常被问到,必须会!这篇文章将让小白有个大体框架,知道怎么个事,面试中可以有话说,也能让佬更加巩固知识点。TCP是一个可靠的传输协议,为了保证它的可靠性,出现七七八八的机制,它可能有数据的破坏、丢包、重复以及分片顺序混乱等问题,TCP通过序......
  • 爬虫工作量由小到大的思维转变---<第六十四章 > Scrapy利用Bloom过滤器增强爬虫的页面去
    前言:        网络爬虫系统是信息时代获取和管理网络数据的重要工具,广泛应用于搜索引擎索引、数据聚合、在线研究等领域。随着网络信息的海量增长,爬虫系统不可避免地会面临重复内容的爬取问题。这不仅浪费了计算资源和网络带宽,而且还会降低数据处理的效率,并可能引起网......
  • 爬虫案例
    BS爬取笔趣阁小说数据#-*-coding:utf-8-*-#author:heart#blog_url:https://www.cnblogs.com/ssrheart/#time:2024/3/30importrandomimporttimeimportrequestsfromfake_useragentimportUserAgentfrombs4importBeautifulSoupimportosheaders=......
  • 爬虫介绍
    Python爬虫(1)介绍Python爬虫是一种自动化获取互联网数据的技术,它通过编写程序实现自动访问网站并抓取所需的数据。爬虫是一种自动化获取互联网数据的技术,通过模拟浏览器行为,向目标网站发送请求并获取响应,然后解析响应中的数据。(2)爬虫的常用库(1)requests用于发送HTTP请......
  • Python+selenium+chromedriver实现自动化爬虫(一)安装
    Python+selenium+chromedriver实现自动化爬虫(一)安装一、概述1.python作为程序语言2.selenium作为库函数3.chromedriver.exe作为调用的可执行程序二、安装(一)Python安装(二)selenium安装安装好python后,使用pipinstallselenium安装好selenium库函数,其中pip安装换源及更新......
  • 某宝之店铺id与旺旺号爬虫爬取
    1.先上昨日(24-3-29)图ShopId:旺旺号文章正文:随着互联网的快速发展,大数据时代已经到来。在这个时代,数据成为了宝贵的资源,而如何高效、自动化地获取数据成为了许多企业和开发者关注的焦点。本文将详细介绍如何利用协议爬取、自动化技术与隧道代理相结合,轻松采集淘宝店铺信息......
  • Python实现反爬虫
    环境Python3.12安装fastapipipinstall"fastapi[all]"代码fromfastapiimportFastAPI,Responsefromfastapi.responsesimportFileResponseapp=FastAPI()@app.get('/')defindex():resp=FileResponse('data.gz')res......
  • 爬虫-今日头条我的收藏-增量式导入到Elastic Search(四)
    背景:继成功导入输入数据到mongodb,sqlite3之后,发现了一些问题,(写到此处觉得还是有些地方没有去深入的学习可能mongodb已经有解决方案了?):对关键字查询支持不友好,如果要在sql中拆分出不同的关键字sql会比较麻烦。另外排序不友好,如何把最匹配的记录放在最前面?elasticsearch是对搜......