前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python网络爬虫(5)BeautifulSoup的使用示范

python网络爬虫(5)BeautifulSoup的使用示范

作者头像
嘘、小点声
发布2019-07-31 17:24:40
9780
发布2019-07-31 17:24:40
举报
文章被收录于专栏:嘘、小点声嘘、小点声

创建并显示原始内容

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

代码语言:javascript
复制
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则内容直接显示。

代码语言:javascript
复制
print(soup.name)
print(soup.title.name)
print(soup.title)
print(soup.a)

控制台输出效果如下:

显示属性

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

代码语言:javascript
复制
print(soup.p['class'])
print(soup.p.attrs)

输出结果:

内容文字

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

代码语言:javascript
复制
print(soup.p.string)
print(type(soup.p.string))

效果:

显示注释

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

代码语言:javascript
复制
print(soup.a.string)
print(type(soup.a.string))

文档相关结点

直接子节点数组

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

代码语言:javascript
复制
print(soup.body.contents)

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

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

代码语言:javascript
复制
for i in soup.body.children:
    print(i,end='')

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

子、孙节点

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

代码语言:javascript
复制
for i in soup.body.descendants:
    print(i)

效果:

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

代码语言:javascript
复制
print(soup.strings)
print('------------------------')
for text in soup.strings:
    print(text,end='')

效果:

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

代码语言:javascript
复制
for text in soup.stripped_strings:
    print(text)

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

父节点相关

父节点parent

代码语言:javascript
复制
print(soup.title)
print(soup.title.parent)

效果:

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

代码语言:javascript
复制
for i in soup.a.parents:
    print(i.name)

效果:

兄弟节点等

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

代码语言:javascript
复制
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标签
代码语言:javascript
复制
print(soup.find_all('b'))

输出:

查找所有b开头的标签

配合正则表达式使用

代码语言:javascript
复制
import re
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)

输出:

查找a开头和b开头的标签
代码语言:javascript
复制
print(soup.find_all(["a", "b"]))

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

查找所有标签,True可以匹配任何值
代码语言:javascript
复制
for tag in soup.find_all(True):
  print(tag.name)

输出:

自定义过滤

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

代码语言:javascript
复制
def hasClass_Id(tag):
    return tag.has_attr('class') and tag.has_attr('id')
print(soup.find_all(hasClass_Id))

效果:

查找关键词参数kwargs并输出

查找id参数为link2的标签
代码语言:javascript
复制
print(soup.find_all(id='link2'))

输出:

查找链接中含有elsie的标签

配合正则表达式

代码语言:javascript
复制
print(soup.find_all(href=re.compile("elsie")))

输出:

查找所有有id属性的标签
代码语言:javascript
复制
print(soup.find_all(id=True))

输出:

查找所有a标签且class内容为sister
代码语言:javascript
复制
print(soup.find_all("a", class_="sister"))

输出:

查找所有链接含有elsie的标签,id为link1
代码语言:javascript
复制
print(soup.find_all(href=re.compile("elsie"), id='link1'))

输出:

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

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

代码语言:javascript
复制
data_soup = BeautifulSoup('<div data-foo="value">foo!</div>','lxml')
print(data_soup.find_all(attrs={"data-foo": "value"}))

输出:

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

输入:

代码语言:javascript
复制
print(soup.find_all(text=["Tillie", "Elsie", "Lacie"]))
print(soup.find_all(text=re.compile("Dormouse")))

输出:

通过limit参数限制查找数量

输入:

代码语言:javascript
复制
print(soup.find_all("a", limit=2))

输出只有两个:

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

soup位于根处

代码语言:javascript
复制
print(soup.find_all("title"))
print(soup.find_all("title", recursive=False))

输出:

使用CSS选择器查找

代码语言:javascript
复制
#直接查找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"]')

输出:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建并显示原始内容
  • 提取对象内容和属性
    • 提取Tag对象
      • 显示属性
        • 内容文字
          • 显示注释
          • 文档相关结点
            • 直接子节点数组
              • 子、孙节点
                • 父节点相关
                  • 兄弟节点等
                  • BeautifulSoup的搜索方法
                    • find_all中参数name查找名称标记
                      • 查找所有b标签
                      • 查找所有b开头的标签
                      • 查找a开头和b开头的标签
                      • 查找所有标签,True可以匹配任何值
                      • 自定义过滤
                    • 查找关键词参数kwargs并输出
                      • 查找id参数为link2的标签
                      • 查找链接中含有elsie的标签
                      • 查找所有有id属性的标签
                      • 查找所有a标签且class内容为sister
                      • 查找所有链接含有elsie的标签,id为link1
                      • 不能表达的属性的解决方案
                    • 通过text参数查找文本内容并过滤
                      • 通过limit参数限制查找数量
                        • 通过recursive参数只查找直接子节点
                        • 使用CSS选择器查找
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档