参考文档:Beautiful Soup 4.4.0 文档 — Beautiful Soup 4.2.0 中文 文档
"""
下面是python爬虫数据解析时多用的一些操作
"""
# # 环境
# pip install bs4
# pip install lxml
from bs4 import BeautifulSoup
html_doc = '''
<html>
<head>
<title>The Dormouse's 故事 </title>
<a>都是骗人的</a>
<title>你要我怎样 </title>
</head>
<body>
<body>
<p class="title"><b>The Dormouse's 故事 </b></p>
<p class="story">Once upon a time 有三姐妹; 她们的名字是
<a href="http://example.com/elsie" class="大姐" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="二姐 在他乡" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="小妹" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
'''
soup = BeautifulSoup(html_doc, 'lxml') # 创建一个BeautifulSoup对象,第二个参数指定解析器
# print(type(soup))
# # 按照标准的缩进格式的结构输出BeautifulSoup对象的内容
# print(soup.prettify())
# print(soup.p.prettify())
# # 直接获取标签
# print(soup.a, type(soup.a)) # 表面上返回第一个a标签,实际上返回的是一个Tag对象
# print(soup.body.p)
# print(soup.body.parent)
# print(soup.body.name)
# # lxml解析器,获取多值属性
# soup = BeautifulSoup('<p class="body strikeout"></p>', 'lxml')
# print(soup.p['class']) # 返回p标签class属性值,为一个列表
# # lxml解析器,获取单值属性
# soup = BeautifulSoup('<p class="body"></p>', 'lxml')
# print(soup.p['class']) # 返回p标签class属性值,为一个列表
# # xml解析器,获取属性值
# xml_soup = BeautifulSoup('<p class="body strikeout"></p>', 'xml')
# print(xml_soup.p['class'])
# # find_all方法
# print(soup.find_all('b')) # 返回所有b标签,为一个列表,没找到,返回空列表
# print(soup.find_all(id='link2')) # 返回所有id属性值为 link2 的标签
# print(soup.find_all('a', class_="在他乡")) # 返回所有标签名为a,class属性值为 "在他乡" 的标签
# data_soup = BeautifulSoup('<div data-foo="value">foo!</div>', 'lxml') # 有些标签属性不能在搜索中使用,比如HTML5中的 data-* 属性,但是可以通过find_all方法的attrs参数定义一个字典参数来搜索包含特殊属性的标签
# print(data_soup.find_all(data-foo="value"))
# print(data_soup.find_all(attrs={"data-foo": "value"}))
# # find方法
# print(soup.find('a')) # find方法返回第一个a标签,没有找到,返回None
# # 正则表达式的应用
# import re
# print(soup.find_all(re.compile('^b')))
# # 同时获取不同标签
# print(soup.find_all(['a', 'b']))
# # BeautifulSoup对象的 .original_encoding属性记录了自动识别编码的结果
# print(soup.original_encoding)
'''
CSS选择器:select方法,返回一个列表
'''
# # 通过标签选择器查找
# print(soup.select('title')) # 找到一个或多个,都返回一个列表;没有找到,返回一个空列表
# print(soup.select('body a')) # body标签下的所有a标签,空格表示多个层级
# print(soup.select('head > title')) # head标签下的直接子标签,>表示一个层级
# # 通过类选择器查找
# print(soup.select('.大姐')) # .代表class
# # 通过 id 选择器查找
# print(soup.select('#link1')) # #代表id
# print(soup.select('a#link2'))
# print(soup.select('#link1, #link2'))
# print(soup.select("#link1, title"))
# 通过层级选择器查找
# print(soup.select('p .二姐')) # 混合条件
# # 通过属性选择器查找
# 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"]'))
# 通过伪类选择器查找
print(soup.select('head title:nth-child(2)')) # title标签的父标签下的第2个title标签
# # get_text():获取BeautifulSoup对象或Tag对象的所有文本内容包括子孙标签中的内容
# print(soup.get_text())
# print(soup.get_text('|', strip=True)) # 指定分隔符,去除空白
# # soup.strings:返回一个迭代器对象,获取BeautifulSoup对象或Tag对象的所有文本内容包括子孙标签中的内容。如果本标签下无子标签或有且仅有一个子标签,soup.string返回子标签的文本内容,如果有多个子标签或孙子标签,soup.string返回None
# for string in soup.strings:
# print(repr(string))
# for string in soup.stripped_strings: # stripped_strings能去除首尾空格空行
# print(repr(string))
# print(soup.find('head').string)
# # 获取属性值 get('属性的名字')
# print(soup.find('a').get('class'))