问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

关于python中BeautifulSoup多层嵌套下标签内容寻找使用方法。

发布网友 发布时间:2022-04-18 17:41

我来回答

4个回答

懂视网 时间:2022-04-18 22:02

这篇文章主要给大家介绍了python中 Beautiful Soup 模块的搜索方法函数。 方法不同类型的过滤参数能够进行不同的过滤,得到想要的结果。文中介绍的非常详细,对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。

前言

我们将利用 Beautiful Soup 模块的搜索功能,根据标签名称、标签属性、文档文本和正则表达式来搜索。

搜索方法

Beautiful Soup 内建的搜索方法如下:

  • find()

  • find_all()

  • find_parent()

  • find_parents()

  • find_next_sibling()

  • find_next_siblings()

  • find_previous_sibling()

  • find_previous_siblings()

  • find_previous()

  • find_all_previous()

  • find_next()

  • find_all_next()

  • 使用 find() 方法搜索

    首先还是需要建立一个 HTML 文件用来做测试。


    <html>
    <body>
    <p class="ecopyramid">
     <ul id="producers">
     <li class="producerlist">
     <p class="name">plants</p>
     <p class="number">100000</p>
     </li>
     <li class="producerlist">
     <p class="name">algae</p>
     <p class="number">100000</p>
     </li>
     </ul>
     <ul id="primaryconsumers">
     <li class="primaryconsumerlist">
     <p class="name">deer</p>
     <p class="number">1000</p>
     </li>
     <li class="primaryconsumerlist">
     <p class="name">rabbit</p>
     <p class="number">2000</p>
     </li>
     </ul>
     <ul id="secondaryconsumers">
     <li class="secondaryconsumerlist">
     <p class="name">fox</p>
     <p class="number">100</p>
     </li>
     <li class="secondaryconsumerlist">
     <p class="name">bear</p>
     <p class="number">100</p>
     </li>
     </ul>
     <ul id="tertiaryconsumers">
     <li class="tertiaryconsumerlist">
     <p class="name">lion</p>
     <p class="number">80</p>
     </li>
     <li class="tertiaryconsumerlist">
     <p class="name">tiger</p>
     <p class="number">50</p>
     </li>
     </ul>
    </p>
    </body>
    </html>

    我们可以通过 find() 方法来获得 <ul> 标签,默认情况下会得到第一个出现的。接着再获取 <li> 标签,默认情况下还是会得到第一个出现的,接着获得 <p> 标签,通过输出内容来验证是否获取了第一个出现的标签。


    from bs4 import BeautifulSoup
    with open('search.html','r') as filename:
     soup = BeautifulSoup(filename,'lxml')
    first_ul_entries = soup.find('ul')
    print first_ul_entries.li.p.string

    find() 方法具体如下:


    find(name,attrs,recursive,text,**kwargs)

    正如上代码所示,find() 方法接受五个参数:name、attrs、recursive、text 和 **kwargs 。name 、attrs 和 text 参数都可以在 find() 方法充当过滤器,提高匹配结果的精确度。

    搜索标签

    除了上面代码的搜索 <ul> 标签外,我们还可以搜索 <li> 标签,返回结果也是返回出现的第一个匹配内容。


    tag_li = soup.find('li')
    # tag_li = soup.find(name = "li")
    print type(tag_li)
    print tag_li.p.string

    搜索文本

    如果我们只想根据文本内容来搜索的话,我们可以只传入文本参数 :


    search_for_text = soup.find(text='plants')
    print type(search_for_text)
    <class 'bs4.element.NavigableString'>

    返回的结果也是 NavigableString 对象 。

    根据正则表达式搜索

    如下的一段 HTML 文本内容


    <p>The below HTML has the information that has email ids.</p>
     abc@example.com 
    <p>xyz@example.com</p> 
     <span>foo@example.com</span>

    可以看到 abc@example 邮件地址并没有包括在任何标签内,这样就不能根据标签来找到邮件地址了。这个时候,我们可以使用正则表达式来进行匹配。


    email_id_example = """
     <p>The below HTML has the information that has email ids.</p>
     abc@example.com
     <p>xyz@example.com</p>
     <span>foo@example.com</span>
     """
    email_soup = BeautifulSoup(email_id_example,'lxml')
    print email_soup
    # pattern = "w+@w+.w+"
    emailid_regexp = re.compile("w+@w+.w+")
    first_email_id = email_soup.find(text=emailid_regexp)
    print first_email_id

    在使用正则表达式进行匹配时,如果有多个匹配项,也是先返回第一个。

    根据标签属性值搜索

    可以通过标签的属性值来搜索:


    search_for_attribute = soup.find(id='primaryconsumers')
    print search_for_attribute.li.p.string

    根据标签属性值来搜索对大多数属性都是可用的,例如:id、style 和 title 。

    但是对以下两种情况会有不同:

  • 自定义属性

  • 类 ( class ) 属性

  • 我们不能再直接使用属性值来搜索了,而是得使用 attrs 参数来传递给 find() 函数。

    根据自定义属性来搜索

    在 HTML5 中是可以给标签添加自定义属性的,例如给标签添加 属性。

    如下代码所示,如果我们再像搜索 id 那样进行操作的话,会报错的,Python 的变量不能包括 - 符号。


    customattr = """
     <p data-custom="custom">custom attribute example</p>
     """
    customsoup = BeautifulSoup(customattr,'lxml')
    customsoup.find(data-custom="custom")
    # SyntaxError: keyword can't be an expression

    这个时候使用 attrs 属性值来传递一个字典类型作为参数进行搜索:


    using_attrs = customsoup.find(attrs={'data-custom':'custom'})
    print using_attrs

    基于 CSS 中的 类 进行搜索

    对于 CSS 的类属性,由于在 Python 中 class 是个关键字,所以是不能当做标签属性参数传递的,这种情况下,就和自定义属性一样进行搜索。也是使用 attrs 属性,传递一个字典进行匹配 。

    除了使用 attrs 属性之外,还可以使用 class_ 属性进行传递,这样与 class 区别开了,也不会导致错误。


    css_class = soup.find(attrs={'class':'producerlist'})
    css_class2 = soup.find(class_ = "producerlist")
    print css_class
    print css_class2

    使用自定义的函数搜索

    可以给 find() 方法传递一个函数,这样就会根据函数定义的条件进行搜索。

    函数应该返回 true 或者是 false 值。


    def is_producers(tag):
     return tag.has_attr('id') and tag.get('id') == 'producers'
    tag_producers = soup.find(is_producers)
    print tag_producers.li.p.string

    代码中定义了一个 is_producers 函数,它将检查标签是否具体 id 属性以及属性值是否等于 producers,如果符合条件则返回 true ,否则返回 false 。

    联合使用各种搜索方法

    Beautiful Soup 提供了各种搜索方法,同样,我们也可以联合使用这些方法来进行匹配,提高搜索的准确度。


    combine_html = """
     <p class="identical">
     Example of p tag with class identical
     </p>
     <p class="identical">
     Example of p tag with class identical
     <p>
     """
    combine_soup = BeautifulSoup(combine_html,'lxml')
    identical_p = combine_soup.find("p",class_="identical")
    print identical_p

    使用 find_all() 方法搜索

    使用 find() 方法会从搜索结果中返回第一个匹配的内容,而 find_all() 方法则会返回所有匹配的项。

    find() 方法中用到的过滤项,同样可以用在 find_all() 方法中。事实上,它们可以用到任何搜索方法中,例如:find_parents()find_siblings() 中 。


    # 搜索所有 class 属性等于 tertiaryconsumerlist 的标签。
    all_tertiaryconsumers = soup.find_all(class_='tertiaryconsumerlist')
    print type(all_tertiaryconsumers)
    for tertiaryconsumers in all_tertiaryconsumers:
     print tertiaryconsumers.p.string

    find_all() 方法为 :


    find_all(name,attrs,recursive,text,limit,**kwargs)

    它的参数和 find() 方法有些类似,多个了 limit 参数。limit 参数是用来限制结果数量的。而 find() 方法的 limit 就是 1 了。

    同时,我们也能传递一个字符串列表的参数来搜索标签、标签属性值、自定义属性值和 CSS 类。


    # 搜索所有的 p 和 li 标签
    p_li_tags = soup.find_all(["p","li"])
    print p_li_tags
    print
    # 搜索所有类属性是 producerlist 和 primaryconsumerlist 的标签
    all_css_class = soup.find_all(class_=["producerlist","primaryconsumerlist"])
    print all_css_class
    print

    搜索相关标签

    一般情况下,我们可以使用 find()find_all() 方法来搜索指定的标签,同时也能搜索其他与这些标签相关的感兴趣的标签。

    搜索父标签

    可以使用 find_parent() 或者 find_parents() 方法来搜索标签的父标签。

    find_parent() 方法将返回第一个匹配的内容,而 find_parents() 将返回所有匹配的内容,这一点与 find() find_all() 方法类似。


    # 搜索 父标签
    primaryconsumers = soup.find_all(class_='primaryconsumerlist')
    print len(primaryconsumers)
    # 取父标签的第一个
    primaryconsumer = primaryconsumers[0]
    # 搜索所有 ul 的父标签
    parent_ul = primaryconsumer.find_parents('ul')
    print len(parent_ul)
    # 结果将包含父标签的所有内容
    print parent_ul
    print
    # 搜索,取第一个出现的父标签.有两种操作
    immediateprimary_consumer_parent = primaryconsumer.find_parent()
    # immediateprimary_consumer_parent = primaryconsumer.find_parent('ul')
    print immediateprimary_consumer_parent

    搜索同级标签

    Beautiful Soup 还提供了搜索同级标签的功能。

    使用函数 find_next_siblings() 函数能够搜索同一级的下一个所有标签,而 find_next_sibling() 函数能够搜索同一级的下一个标签。


    producers = soup.find(id='producers')
    next_siblings = producers.find_next_siblings()
    print next_siblings

    同样,也可以使用 find_previous_siblings() find_previous_sibling() 方法来搜索上一个同级的标签。

    搜索下一个标签

    使用 find_next() 方法将搜索下一个标签中第一个出现的,而 find_next_all() 将会返回所有下级的标签项。


    # 搜索下一级标签
    first_p = soup.p
    all_li_tags = first_p.find_all_next("li")
    print all_li_tags

    搜索上一个标签

    与搜索下一个标签类似,使用 find_previous()find_all_previous() 方法来搜索上一个标签。

    热心网友 时间:2022-04-18 19:10

    你写错了,是class,多了一个下划线

    热心网友 时间:2022-04-18 20:28

    你的soup是怎么建立的?是用request对象的text么?
    理论上语法没有错(检查一下class_后面的是不是完全相同)
    至于楼下说多一个下划线的不知道class是关键字不能当参数名字么

    热心网友 时间:2022-04-18 22:03

    BeautifulSoup解析不要用‘lxml’,会丢失内容,用‘html.parser’
    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
    乾隆小时候的书童是谁 下面对句式判断有误的一项是( ) A.当立者乃公子扶苏(判断句) ...为折线,把 折起,使平面 平面 ,连接 (1)求证: ;(2)求二面角 图中由线段OA、AB组成的折线表示的是小明步行所走的路程和时间之间的关... 动态图像粒度粒形分析仪 oppor9splus视频通话怎么开美颜 微信视频聊天怎么开美颜oppor9 谁家出售二手胶囊填充机NJP1200 NJP-1200A硬胶囊填充机仪器特点简介 NJP-1200A硬胶囊填充机仪器参数 公务员考试需网络工程师证,有网络应用工程师可以报考 开斗鱼户外手机直播,哪些手机可以,iphone6s可以吗,或者推荐一些,手机直播用的是前置摄像头还 摄像机户外直播需要哪些设备 户外活动视频直播用手机可行吗?如果不行,有小型的摄像机吗? 我现在有一场户外比赛需要直播,用哪个比较好,可以连自己的摄像机的那种 如何带好业务员 罗斯3.0实战如何? 请问罗斯3.0有雪碧配色的吗? 罗斯3.0和詹姆斯9代球鞋推荐 罗斯3.0穿41码,罗斯4.5要穿几码? 罗斯3和罗斯3.5有啥区别? 罗斯3.0鞋码问题 罗斯3.0 罗斯3.5 詹姆斯10 该买哪双? 罗斯3.0都加强的那些方面? 科7科8罗斯2.5罗斯9.8罗斯3.0罗斯3.5詹9 哪个好? adi罗斯3.0脚感如何 罗斯3.0球鞋什么时候出 阿迪刚出的罗斯3.0性能怎样 有什么科技 小前锋罗斯3.0和詹10哪个好 罗斯3.0目前多少钱 梦见满家的虫子.爬的特快.啥意思.求解 梦见满屋都是虫在往上爬,切碎的很多豆角在地上,突然有很多象_虫子出来,直往上爬,密密麻麻 梦见好多黑虫子在屋顶爬满脸 中国证券市场已经退市的股票有哪些? 最近退市5股票有哪些? 怎么样能够免费给宝宝起名呢?起个好听又吉利的。 今年将有哪些股票退市? oppor17亮度为何不亮在室外 手臂突然疼痛是什么回事 胳膊突然疼是怎么回事 我妈妈突然手臂很疼痛是怎么回事 手臂表皮突然有疼痛感觉是怎么回事 有时候感觉胳膊突然一阵刺痛,像有很多根针扎得一样,这是怎么了? 手臂无缘无故酸痛是怎么了 我老公手臂无缘无故疼痛是怎么了 右手臂无缘无故的突然疼痛是怎么回事 胳膊突然阵阵疼痛是为什么?是肌肉拉伤吗? 胳膊突然很酸疼,这是怎么回事? 无缘无故的胳膊酸痛?请问是怎么回事? 右手臂莫名其妙一阵阵的疼痛是怎么回事