#!/usr/bin/env python
# -*- coding: utf-8 -*-
# bs4 是三方庫,在調用的時候,要先在cmd中下載 pip install bs4
import bs4
from bs4 import BeautifulSoup
content = '''<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>soup測試</title>
<title class="warm">你那溫情的一笑,搞得我瑟瑟發抖</title>
</head>
<body>
<div class="tang">
<ul>
<li class="hello" id="world"><a href="http://www.baidu.com" title="出塞"><!--秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山--></a></li>
<list><a href="https://www.baidu.com" title="出塞" style="font-weight: bold"><!--秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山--></a></list>
<li><a href="http://www.163.com" class="taohua" title="huahua">人面不知何處去,桃花依舊笑春風</a></li>
<lists class="hello"><a href="http://mi.com" id="hong" title="huahua">去年今日此門中,人面桃花相映紅</a></lists>
<li id="wo"><a href="http://qq.com" name="he" id="gu">故人西辭黃鶴樓,煙花三月下揚州</a></li>
</ul>
<ul>
<li class="hello" id="sf"><a href="http://www.baidu.com" title="出塞"><!--秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山--></a></li>
<list><a href="https://www.baidu.com" title="出塞"><!--秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山--></a></list>
<li><a href="http://www.163.com" class="taohua">人面不知何處去,桃花依舊笑春風</a></li>
<lists class="hello"><a href="http://mi.com" id="fhsf">去年今日此門中,人面桃花相映紅,不知桃花何處去,出門依舊笑楚風</a></lists>
<li id="fs"><a href="http://qq.com" name="he" id="gufds">故人西辭黃鶴樓,煙花三月下揚州</a></li>
</ul>
</div>
<div id="meng">
<p class="jiang">
<span>三國猛將</span>
<ol>
<li>關羽</li>
<li>張飛</li>
<li>趙雲</li>
<li>馬超</li>
<li>黃忠</li>
</ol>
<div class="cao">
<ul>
<li>典韋</li>
<li>許褚</li>
<li>張遼</li>
<li>張郃</li>
<li>于禁</li>
<li>夏侯惇</li>
</ul>
</div>
</p>
</div>
</body>
</html>'''
# 使用bs4推薦的解析方式:lxml (如果初次使用,需要在終端安裝: pip install lxml
soup = BeautifulSoup(content, 'lxml') # str 數據轉換成soup對象, 對象是一個文檔內容
# print(soup)
# print(type(soup)) # <class 'bs4.BeautifulSoup'>
# Tag 通俗的將就是HTML中的一個個標籤
ret = soup.title # 使用.只能匹配獲取第一個
# print(ret) # <title>soup測試</title>
# print(type(ret)) # <class 'bs4.element.Tag'>
# NavigableSrting:既然我們已經得到了標籤,那麼問題來了,我們想要獲取標籤內部的文字怎麼辦呢?
# 很簡單,用.string 即可
ret = soup.title.string
# print(ret) # soup測試
# print(type(ret)) # <class 'bs4.element.NavigableString'>
# Comment:對象是一個特殊類型的NavigableString對象,其輸出的內容不包括註釋符號
# <!--xxxxx--> comment 註釋
# <class 'bs4.element.Comment'>
ret = soup.li.string
# print(ret) # 秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山
# print(type(ret)) # <class 'bs4.element.Comment'>
# 獲取屬性的值 !!!
li = soup.li
# 方法一:
ret = li.get('class') # 如果沒有獲取到改屬性,也不會報錯,返回一個None
# print(ret) # ['hello']
# 方法二:
ret = li['class']
# print(ret) # ['hello']
# 方法三:
ret = li.attrs['id']
# print(ret) # world
# 可以使用遍歷來取出我們想要的數據
ret = soup.contents # 以一個列表的形式,將真個頁面裏的標籤返回
ret = soup.ul.contents
# print(ret)
# print(len(ret))
# for data in ret:
# if data != '\n':
# # print(data)
# # print(data.string)
# try:
# print(data['id'])
# except:
# pass
'''
<li class="hello" id="world"><a href="http://www.baidu.com" title="出塞"><!--秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山--></a></li>
<list><a href="https://www.baidu.com" style="font-weight: bold" title="出塞"><!--秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山--></a></list>
<li><a class="taohua" href="http://www.163.com" title="huahua">人面不知何處去,桃花依舊笑春風</a></li>
<lists class="hello"><a href="http://mi.com" id="hong" title="huahua">去年今日此門中,人面桃花相映紅</a></lists>
<li id="wo"><a href="http://qq.com" id="gu" name="he">故人西辭黃鶴樓,煙花三月下揚州</a></li>
秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山
秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山
人面不知何處去,桃花依舊笑春風
去年今日此門中,人面桃花相映紅
故人西辭黃鶴樓,煙花三月下揚州
world
wo
'''
# 返回一個迭代器
ret = soup.ul.children
# print(ret)
# for data in ret:
# if data != '\n':
# print(data)
'''
<list_iterator object at 0x104f75208>
<li class="hello" id="world"><a href="http://www.baidu.com" title="出塞"><!--秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山--></a></li>
<list><a href="https://www.baidu.com" style="font-weight: bold" title="出塞"><!--秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山--></a></list>
<li><a class="taohua" href="http://www.163.com" title="huahua">人面不知何處去,桃花依舊笑春風</a></li>
<lists class="hello"><a href="http://mi.com" id="hong" title="huahua">去年今日此門中,人面桃花相映紅</a></lists>
<li id="wo"><a href="http://qq.com" id="gu" name="he">故人西辭黃鶴樓,煙花三月下揚州</a></li>
'''
# 返回的也是一個迭代器
ret = soup.ul.descendants
# print(ret) # <generator object descendants at 0x1045e7570>
#
# for data in ret:
# if data != '\n':
# print(data)
#
# 搜索功能
# find 方法
# 方法一:
ret = soup.find(name='li', attrs={'id':'wo'})
# print(ret)
# <li id="wo"><a href="http://qq.com" id="gu" name="he">故人西辭黃鶴樓,煙花三月下揚州</a></li>
# 方法二:
ret = soup.find(name='li', id='wo')
# print(ret)
# <li id="wo"><a href="http://qq.com" id="gu" name="he">故人西辭黃鶴樓,煙花三月下揚州</a></li>
# class 是關鍵字,加一個下劃線就可以了
ret = soup.find(name='lists', class_='hello')
# print(ret)
# <lists class="hello"><a href="http://mi.com" id="hong" title="huahua">去年今日此門中,人面桃花相映紅</a></lists>
# 方法三:
ret = soup.find(name='lists', attrs={'class': 'hello'})
# print(ret)
# <lists class="hello"><a href="http://mi.com" id="hong" title="huahua">去年今日此門中,人面桃花相映紅</a></lists>
# find_all 方法 : 找到的是所有的匹配元素
ret = soup.find_all(name='lists', attrs={'class': 'hello'})
print(ret)
# [<lists class="hello"><a href="http://mi.com" id="hong" title="huahua">去年今日此門中,人面桃花相映紅</a></lists>, <lists class="hello"><a href="http://mi.com" id="fhsf">去年今日此門中,人面桃花相映紅,不知桃花何處去,出門依舊笑楚風</a></lists>]
# limit=5 限制條件,獲取前5條數據
ret = soup.find_all(name='li',limit=5)
# print(len(ret))
#### soup.select() 返回類型是list
##
# . 表示類名,# 表示id
ret = soup.select('li#world') # li標籤下 ID 爲 : world
# print(ret)
# print(len(ret))
ret = soup.select('li.hello') # li標籤下 類 爲 : hello
# print(ret)
# xpath / 相當於 soup中 >
ret = soup.select('div.tang > ul > li,list')
# print(ret)
# print(len(ret))
# !!! 可以使用[表示條件],但是不能加@
# ! ! ! 不能使用contains
ret = soup.select('div[class="tang"]')
print(ret)