BeautifulSoup ライブラリの使用状況分析
I.はじめに
BeautifulSoup は HTML ドキュメント解析ライブラリで、クローラーがデータを解析するときに非常に役立ちます。次にその使用法を文書化します。
2. 準備
インポートライブラリ
- bs4 インポートから BeautifulSoup
美しいSoupオブジェクトを作成する
- ファイルを通じて美しいSoupオブジェクトを作成します
file = open("./Test.html",encoding="utf-8")
soup = BeautifulSoup(file,"html.parser")
- テキスト コンテンツを通じて BeautifulSoup オブジェクトを作成します
content = '''
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="content-type" />
<meta content="IE=Edge" http-equiv="X-UA-Compatible" />
<meta content="always" name="referrer" />
<link href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css" rel="stylesheet" type="text/css" />
<title attr1="val1" attr2="val2">百度一下,你就知道 </title>
<ha attr1="val1" attr2="val2"><!--我是注释里的内容--></ha>
</head>
<body link="#0000cc">
<div id="wrapper">
<div id="head">
<div class="head_wrapper">
<div id="u1">
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 </a>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 </a>
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图 </a>
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频 </a>
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧 </a>
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon" style="display: block;">更多产品 </a>
</div>
</div>
</div>
</div>
</body>
</html>
'''
soup = BeautifulSoup(content,"html.parser")
これはより一般的に使用されますが、実際の使用では、コンテンツは Web ページによってリアルタイムでキャプチャされたテキスト コンテンツに置き換えられます。
次に、上記のテキストをデータ ソースとして使用して説明します。以下のすべてのメソッドはこのテキストの分析に基づいています。
3. タイプ
- 美しいスープ
- 鬼ごっこ
- ナビゲート可能な文字列
- コメント
美しいスープタイプ
先ほど作成したスープ オブジェクトのタイプは BeautifulSoup です。印刷できます
print(type(soup))
输出:<class 'bs4.BeautifulSoup'>
タグの種類
タグのタイプは非常に重要なタイプです。タグとは何ですか。次の図に示すように、XML のタグに似ています。
<div id="u1"> <!-- 这是一个Tag-->
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 </a> <!--这也是一个Tag-->
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 </a> <!--俺也一样-->
</div>
タグは、名前、属性、文字列の 3 つの部分に分けることができます。構造を図に示します
#获得找到的第一个名字为a的标签
print(soup.a)
#结果: <a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 </a>
#打印名字
print(soup.a.name)
#结果:a
#打印属性
print(soup.a.attrs)
#结果:{'class': ['mnav'], 'href': 'http://news.baidu.com', 'name': 'tj_trnews'}
#打印内容
print(soup.a.string)
#结果:新闻
NavigableString 型と Comment 型
これら 2 つは実際には Tag の文字列コンテンツです。違いは、コンテンツが完全にコメントされている場合は Comment タイプであり、それ以外の場合は NavigableString タイプであることです。
<title attr1="val1" attr2="val2">百度一下,你就知道 </title> <!--这里的string是NavigableString类型-->
<ha attr1="val1" attr2="val2"><!--我是注释里的内容--></ha> <!--这里的string是Comment类型-->
print(type(soup.title.string))
#结果:<class 'bs4.element.NavigableString'>
print(type(soup.ha.string))
#结果:<class 'bs4.element.Comment'>
print(soup.title.string)
#结果:百度一下,你就知道
print(soup.ha.string)
#结果:我是注释里的内容
#注意上面这里直接获得了注释里的内容
4、トラバース
名前からタグを取得できます。
- たとえば、上記の HTML コンテンツによれば、次のようなラベルを取得できます。
- スープ.ヘッド ヘッドを取得
- Soup.head.title はタグを取得します
が、トラバースしたい場合は他のメソッドを使用する必要があります。次に、その方法を見てみましょう
直接の子ノードを走査する
コンテンツ
- コンテンツを使用して直接の子ノード、リスト型を返す
for item in soup.head.contents:
print(item.name)
'''
结果:
None
meta
None
meta
None
meta
None
link
None
title
None
ha
None
'''
サブタグがすべて出力されていることがわかります (サブタグには何もないノードがいくつかあります)。
子供
- Children を使用して直接の子ノードを返します。listiterator のイテレータ型は
コンテンツと似ていますが、戻り値の型は異なります。
すべての子ノードを反復処理します
子孫
前のコンテンツで取得した直接の子ノードとその子は孫ノードを取得できません。そして子孫はすべての子ノードを取得できます
for item in soup.body.descendants:
print(item.name)
親ノードをトラバースする
- 親は親ノードを取得します
- 親はすべての親ノードを取得します
兄弟ノードを走査する
-
next_sibling 次の兄弟ノード
-
next_siblings 自分の下のすべての兄弟ノード
-
previous_sibling 前の兄弟ノード
-
previous_siblings それ自体の上の兄弟ノード
前方および後方のトラバース
兄弟ノードの走査とは異なり、ここでの前方および後方走査は子ノードに到達できます。ルート ノードから逆方向にトラバースすると、すべてのノードに到達できます。
- next_element 次のノード
- next_elements それ自身の下のすべてのノード
- previous_element 前のノード
- previous_elements それより上のすべてのノード
5. 検索
find_all()
- キーワード検索を指定する
名前を指定してください
#查找 name=“a” 的所有标签
alla = soup.find_all(name="a")
for a in alla:
print(a)
結果
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 </a>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 </a>
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图 </a>
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频 </a>
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧 </a>
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon"> 更多产品 </a>
上記は、soup.find_all("a") と書くこともできます。キーワードが指定されていない場合、デフォルトは名前が条件になります。
テキストを指定する
allItem = soup.find_all(text="新闻 ")
for item in allItem:
print(item)
結果
新闻
ここで見つかったものはすべて文字列であり、タグではないことに注意してください
属性を指定する
名前、テキスト、属性などのキーワードに加えて、属性を表すものもあります。例えば
allItem = soup.find_all(href="//www.baidu.com/more/")
for item in allItem:
print(item)
結果
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon"> 更多产品 </a>
属性が Python キーワード (class など) と一致する場合は、次のようにアンダースコア _ を追加する必要があります。
allItem = soup.find_all(class_="mnav")
for item in allItem:
print(item)
結果
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 </a>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 </a>
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图 </a>
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频 </a>
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧 </a>
複数の条件を追加できます。
allItem = soup.find_all(class_="mnav",href="http://news.baidu.com",name="a")
for item in allItem:
print(item)
結果
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 </a>
指定されたリスト
list = {
"mnav","bri"}
allItem = soup.find_all(class_=list)
for item in allItem:
print(item)
結果
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 </a>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 </a>
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图 </a>
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频 </a>
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧 </a>
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon"> 更多产品 </a>
正規表現を指定する
allItem = soup.find_all(href =re.compile("www."))
for item in allItem:
print(item)
結果
<link href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css" rel="stylesheet" type="text/css"/>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 </a>
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon"> 更多产品 </a>
指定された方法
メソッドを指定します。メソッドをパラメータとして渡すことができますが、このメソッドはパラメータとして Tag を受け取る必要があります。例えば:
def has_attr_name(tag):
return tag.has_attr('name')
allItem = soup.find_all(has_attr_name)
for item in allItem:
print(item)
結果
<meta content="always" name="referrer"/>
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 </a>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 </a>
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图 </a>
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频 </a>
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧 </a>
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon"> 更多产品 </a>
検索()
BeautifulSoup では search() を使って検索することもできますが、私は BeautifulSoup を使い始めたばかりなので、通常は find_all() を使って検索を完了します。これについては詳しくないので書きません...