zoukankan      html  css  js  c++  java
  • Python.BeautifulSoup4

    BeautifulSoup简介

    BeautifulSoup简介Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下:

    Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
    
    Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。
    
    Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。
    
    

    官方文档

    安装BeautifulSoup库

    pip install bs4
    

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

    • Tag
    • Navigable
    • String
    • BeautifulSoupComment

    下文将使用Beautiful Soup各功能解析自己的博客首页:

    import requests
    from bs4 import BeautifulSoup
    
    blog_url = "https://www.cnblogs.com/youngleesin/"
    header={
    "User-Agent":"Mozilla/5.0 (Linux; U; An
    droid 8.1.0; zh-cn; BLA-AL00 Build/HUAW
    EIBLA-AL00) AppleWebKit/537.36 (KHTML, l
    ike Gecko) Version/4.0 Chrome/57.0.2987.13
    2 MQQBrowser/8.9 Mobile Safari/537.36"
    }	
    
    respone = requests.get(blog_url, headers = header)
    
    blog_html = BeautifulSoup(respone.text, "lxml") # respone.text 表示被解析的html内容,lxml表示使用的解析器
    

    标签选择器

    获取标签信息的方法

    # print(blog_html.prettify()) # prettify() 方法格式化显示输出,由于内容较多不展示输出信息
    print("博客园的title是:", blog_html.title.string)
    print("第一个a标签的信息:", blog_html.a)
    print("第一个a标签的名字:", blog_html.a.name)
    print("a标签父标签的名字:", blog_html.a.parent.name)
    print("a标签父标签的父标签的名字:", blog_html.a.parent.parent.name)
    print("title标签的子标签:",blog_html.title.contents)
    print("第一个link标签的信息:", blog_html.link)
    print("link标签的属性:", type(blog_html.link))
    print("link标签的名字:", blog_html.link.name)
    print("link标签的类型:", blog_html.link.attrs)
    print("link标签的href属性是:", blog_html.link.attrs["href"])
    

    运行结果

    博客园的title是: yonugleesin - 博客园
    第一个a标签的信息: <a name="top"></a>
    第一个a标签的名字: a
    a标签父标签的名字: body
    a标签父标签的父标签的名字: html
    title标签的子标签: ['yonugleesin - 博客园']
    第一个link标签的信息: <link href="/bundles/blog-common.css?v=KOZafwuaDasEedEenI5aTy8aXH0epbm6VUJ0v3vsT_Q1" rel="stylesheet" type="text/css"/>
    link标签的属性: <class 'bs4.element.Tag'>
    link标签的名字: link
    link标签的类型: {'type': 'text/css', 'rel': ['stylesheet'], 'href': '/bundles/blog-common.css?v=KOZafwuaDasEedEenI5aTy8aXH0epbm6VUJ0v3vsT_Q1'}
    link标签的href属性是: /bundles/blog-common.css?v=KOZafwuaDasEedEenI5aTy8aXH0epbm6VUJ0v3vsT_Q1
    

    find_all()方法:

    常用通过find_all()方法来查找标签元素:find_all(name, attrs, recursive, text, **kwargs) ,返回一个列表类型,存储查找的结果

    • name:对标签名称的检索字符串
    • attrs:对标签属性值的检索字符串,可标注属性检索
    • recursive:是否对子孙全部检索,默认True
    • text:<>…</>中字符串区域的检索字符串

    name 针对标签名检索字符串

    print("检索所有a标签并输出第一个:", blog_html.find_all("a")[0])
    print("检索所有div标签和a标签的内容:", blog_html.find_all(["div", "a"])) # 由于内容较多不展示输出信息
    print(len(blog_html.find_all(["div", "a"])[1]))
    print(len(blog_html.find_all(["div", "a"])[2]))
    

    运行结果

    检索所有a标签并输出第一个: <a name="top"></a>
    12
    7
    

    遍历前三个a标签,并获取href链接

    for data in blog_html.find_all("a")[0:3]:
    	print(data.get("href"))
    

    运行结果

    None
    https://www.cnblogs.com/youngleesin/
    https://www.cnblogs.com/youngleesin/
    

    attrs 针对标签属性检索字符串

    print("class属性为headermaintitle的a标签:",blog_html.find_all("a",class_="headermaintitle")) # class是python的关键字,所以要加个下划线
    print("name属性为top的a标签:",blog_html.find_all("a",attrs = {"name":"top"}))
    

    运行结果

    class属性为headermaintitle的a标签: [<a class="headermaintitle" href="https://www.cnblogs.com/youngleesin/" id="Header1_HeaderTitle">Young_Leesin</a>]
    name属性为top的a标签: [<a name="top"></a>]
    

    遍历class属性为menu的标签,获取href链接

    for data in blog_html.find_all(class_="menu"):
    	print(data.get("href"))
    

    运行结果

    https://www.cnblogs.com/
    https://www.cnblogs.com/youngleesin/
    https://i.cnblogs.com/EditPosts.aspx?opt=1
    https://msg.cnblogs.com/send/yonugleesin
    https://www.cnblogs.com/youngleesin/rss
    https://i.cnblogs.com/
    

    text 根据文本内容进行选择

    print(blog_html.find_all(text = "博客园")) # 适合用来断言
    

    运行结果

    ['博客园']
    

    find()方法

    find(name,attrs,recursive,text,**kwargs)
    find和find_all的区别是find返回单个元素,findall返回所有元素

    print("针对标签属性检索字符串")
    print(blog_html.find_all(class_="clear"))
    print("---------------------------")
    print(blog_html.find(class_="clear"), "
    ", "
    ")
    
    print("针对文本内容检索字符串")
    print(blog_html.find_all(text = "编辑"))
    print("---------------------------")
    print(blog_html.find(text = "编辑"))
    
    针对标签属性检索字符串
    [<div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>, <div class="clear"></div>]
    ---------------------------
    <div class="clear"></div> 
     
    
    针对文本内容检索字符串
    ['编辑', '编辑', '编辑', '编辑', '编辑', '编辑', '编辑', '编辑', '编辑', '编辑']
    ---------------------------
    编辑
    

    CSS选择器

    通过select()直接传入CSS选择器即可完成选择
    CSS选择器参考资料
    .是通过class进行匹配,#通过id进行匹配,其他方法可以参考上面的超链接

    print(blog_html.select(".headermaintitle"))
    print(blog_html.select("#navigator #navList #blog_nav_sitehome"))
    

    运行结果

    [<a class="headermaintitle" href="https://www.cnblogs.com/youngleesin/" id="Header1_HeaderTitle">Young_Leesin</a>]
    [<a class="menu" href="https://www.cnblogs.com/" id="blog_nav_sitehome">博客园</a>]
    

    获取内容和属性

    print("第2个a标签的属性是:",blog_html.select("a")[1])
    print("第1个li标签内容是:",blog_html.select("li")[0].get_text())
    

    运行结果

    第2个a标签的属性是: <a href="https://www.cnblogs.com/youngleesin/" id="lnkBlogLogo"><img alt="返回主页" id="blogLogo" src="/Skins/custom/images/logo.gif"/></a>
    第1个li标签内容是: 博客园
    

    遍历所有li标签中的内容

    for Li in blog_html.select("li"):
    	print(Li.get_text())
    

    运行结果

    博客园
    首页
    新随笔
    联系
    订阅
    
    管理
    

    遍历所有a标签中id的属性

    i=0
    for a in blog_html.select("a")[0:5]:
    	i=i+1
    	try:
    		print("我是第",i,"个a标签,我的id属性是:",a["id"])
    	except:
    		print("我是第",i,"个a标签,我的id属性是:","sorry,本标签无id属性")
    

    运行结果

    我是第 1 个a标签,我的id属性是: sorry,本标签无id属性
    我是第 2 个a标签,我的id属性是: lnkBlogLogo
    我是第 3 个a标签,我的id属性是: Header1_HeaderTitle
    我是第 4 个a标签,我的id属性是: blog_nav_sitehome
    我是第 5 个a标签,我的id属性是: blog_nav_myhome
    
  • 相关阅读:
    CentOS 6找不到partprobe命令的解决方法
    RTL源码归类与路径
    拓扑排序
    Char、AnsiChar、WideChar、PChar、PAnsiChar、PWideChar 的区别
    Delphi Byte与数据类型之间的转换
    Delphi byte[]转换为int
    Delphi Byte数组与Int String之间的相互转换
    delphi TTcpClient TTcpServer分析
    Delph7中TcpClient和TcpServer用法分析
    动态数组的使用
  • 原文地址:https://www.cnblogs.com/youngleesin/p/11298639.html
Copyright © 2011-2022 走看看