zoukankan      html  css  js  c++  java
  • python网络爬虫(5)BeautifulSoup的使用示范

    创建并显示原始内容

    其中的lxml第三方解释器加快解析速度

    import bs4
    from bs4 import BeautifulSoup
    html_str = """
    <html><head><title>The Dormouse's story</title></head>
    <body>
    <p class="title"><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_str,'lxml')
    print(soup.prettify())
    

    控制台显示出soup需要处理的内容:

    提取对象内容和属性

    搜索包括了所有的标签。默认提取第一个符合条件的标签。

    提取Tag对象

    其中,name用于显示标签名,去掉name则内容直接显示。

    print(soup.name)
    print(soup.title.name)
    print(soup.title)
    print(soup.a)
    

    控制台输出效果如下:

    显示属性

    attrs用于显示属性。class用于显示选中的标签Tag中的类名。

    print(soup.p['class'])
    print(soup.p.attrs)
    

    输出结果:

    内容文字

    显示标记中的文字,NavigableString类型

    print(soup.p.string)
    print(type(soup.p.string))
    

    效果:

    显示注释

    显示注释内容,注意与普通string的区别在于最后的类,用于数据分类

    print(soup.a.string)
    print(type(soup.a.string))
    

    文档相关结点

    直接子节点数组

    结点中的contents输出直接子节点数组,可以通过for逐个输出,通过string属性直接输出内容

    print(soup.body.contents)
    

    输出body标签下的直接子节点:

    结点children输出直接子节点,和contents类似。不一样的是返回了生成器,一点参考:https://www.cnblogs.com/wj-1314/p/8490822.html

    for i in soup.body.children:
        print(i,end='')
    

    添加了end=''用于去掉print的自动换行

    子、孙节点

    结点descendants可以输出子节点和孙节点

    for i in soup.body.descendants:
        print(i)
    

    效果:

    节点strings输出全部子节点内容值

    print(soup.strings)
    print('------------------------') for text in soup.strings: print(text,end='')

    效果:

    节点stripped_strings输出全部内容并去掉回车和空格

    for text in soup.stripped_strings:
        print(text)
    

    print每次输出加上换行后,效果:

    父节点相关

    父节点parent

    print(soup.title)
    print(soup.title.parent)
    

    效果:

    父辈节点parents,这里只输出名字就好了,否则内容过多

    for i in soup.a.parents:
        print(i.name)
    

    效果:

    兄弟节点等

    兄弟节点next_sibling,previous_sibling,另有 :next_siblings,previous_siblings

    print(soup.p.next_sibling.next_sibling)
    print(soup.p.previous_sibling)
    

    效果:

    前后节点:next_element,next_elements等......

    BeautifulSoup的搜索方法

    包括了find_all,find,find_parents等等,这里只举例find_all。

    find_all中参数name查找名称标记

    查找所有b标签

    print(soup.find_all('b'))
    

    输出:

    查找所有b开头的标签

    配合正则表达式使用

    import re
    for tag in soup.find_all(re.compile("^b")):
        print(tag.name)
    

    输出:

    查找a开头和b开头的标签

    print(soup.find_all(["a", "b"]))
    

    输出:(一个数组,过长)

    查找所有标签,True可以匹配任何值

    for tag in soup.find_all(True):
      print(tag.name)
    

    输出:

    自定义过滤

    查找含有class和id属性的Tag标签

    def hasClass_Id(tag):
        return tag.has_attr('class') and tag.has_attr('id')
    print(soup.find_all(hasClass_Id))
    

    效果:

    查找关键词参数kwargs并输出

    查找id参数为link2的标签

    print(soup.find_all(id='link2'))
    

    输出:

    查找链接中含有elsie的标签

    配合正则表达式

    print(soup.find_all(href=re.compile("elsie")))
    

    输出:

    查找所有有id属性的标签

    print(soup.find_all(id=True))
    

    输出:

    查找所有a标签且class内容为sister

    print(soup.find_all("a", class_="sister"))
    

    输出:

    查找所有链接含有elsie的标签,id为link1

    print(soup.find_all(href=re.compile("elsie"), id='link1'))
    

    输出:

    不能表达的属性的解决方案

    在html5中有些属性不被支持,查找时,通过定义字典实现输出

    data_soup = BeautifulSoup('<div data-foo="value">foo!</div>','lxml')
    print(data_soup.find_all(attrs={"data-foo": "value"}))
    

    输出:

    通过text参数查找文本内容并过滤

     输入:

    print(soup.find_all(text=["Tillie", "Elsie", "Lacie"]))
    print(soup.find_all(text=re.compile("Dormouse")))
    

    输出:

    通过limit参数限制查找数量

    输入:

    print(soup.find_all("a", limit=2))
    

    输出只有两个:

    通过recursive参数只查找直接子节点

    soup位于根处

    print(soup.find_all("title"))
    print(soup.find_all("title", recursive=False))
    

    输出:

    使用CSS选择器查找

    #直接查找title标签
    print soup.select("title")
    #逐层查找title标签
    print soup.select("html head title")
    #查找直接子节点
    #查找head下的title标签
    print soup.select("head > title")
    #查找p下的id="link1"的标签
    print soup.select("p > #link1")
    #查找兄弟节点
    #查找id="link1"之后class=sisiter的所有兄弟标签
    print soup.select("#link1 ~ .sister")
    #查找紧跟着id="link1"之后class=sisiter的子标签
    print soup.select("#link1 + .sister")
    
    print soup.select(".sister")
    print soup.select("[class~=sister]")
    
    print soup.select("#link1")
    print soup.select("a#link2")
    
    print soup.select('a[href]')
    
    print soup.select('a[href="http://example.com/elsie"]')
    print soup.select('a[href^="http://example.com/"]')
    print soup.select('a[href$="tillie"]')
    print soup.select('a[href*=".com/el"]')
    

     输出:

  • 相关阅读:
    js array 排序
    element 右键菜单
    Element ui tree 搜索
    threejs CameraHelper 查看照相机的观察范围
    android 错误解决
    数据结构学习--数组
    js 遍历树的层级关系的实现
    一篇文章理清WebGL绘制流程
    最基础的CSS面试题
    display:flex;多行多列布局学习
  • 原文地址:https://www.cnblogs.com/bai2018/p/10964702.html
Copyright © 2011-2022 走看看