BeautifulSoupライブラリ
BeautifulSoup4は、複雑なHTMLドキュメントを複雑なツリー構造に変換します。各ノードはPythonオブジェクトです。すべてのオブジェクトは、次の4つのタイプに要約できます。
- 鬼ごっこ
- NavigableString
- BeautifulSoup
- コメント
鬼ごっこ
素人の言葉で言えば、タグはHTMLのタグです
すべてのコンテンツの要件を満たす最初のラベルを探します。
from bs4 import BeautifulSoup
file = open('./aa.html', 'rb')
html = file.read()
bs = BeautifulSoup(html,"html.parser")
# 获取title标签的所有内容,含标签
print(bs.title)
# 获取head标签的所有内容,含标签
print(bs.head)
# 获取第一个a标签的所有内容,含标签
print(bs.a)
# 类型
print(type(bs.a))
2つの重要な属性は名前と属性です
attrs:ラベルのすべての属性を出力し、取得されたタイプは辞書です
name:出力値はラベル自体の名前です
from bs4 import BeautifulSoup
file = open('./aa.html', 'rb')
html = file.read()
bs = BeautifulSoup(html,"html.parser")
# [document] #bs 对象本身比较特殊,它的 name 即为 [document]
print(bs.name)
# head #对于其他内部标签,输出的值便为标签本身的名称
print(bs.head.name)
# 在这里,我们把 a 标签的所有属性打印输出了出来,得到的类型是一个字典。
print(bs.a.attrs)
#还可以利用get方法,传入属性的名称,二者是等价的
print(bs.a['class']) # 等价 bs.a.get('class')
# 可以对这些属性和内容等等进行修改
bs.a['class'] = "newClass"
print(bs.a)
# 还可以对这个属性进行删除
del bs.a['class']
print(bs.a)
NavigableString
ラベルのコンテンツを取得したので、問題は、ラベル内にテキストを取得したい場合はどうすればよいかということです。非常にシンプルで、.stringを使用するだけです
from bs4 import BeautifulSoup
file = open('./aa.html', 'rb')
html = file.read()
bs = BeautifulSoup(html,"html.parser")
#获取title标签的内部的文字内容
print(bs.title.string)
print(type(bs.title.string))
BeautifulSoup
BeautifulSoupオブジェクトは、ドキュメントのコンテンツを表します。ほとんどの場合、これは特別なタグであるTagオブジェクトと見なすことができます。そのタイプ、名前、および属性は、次のように個別に取得できます。
from bs4 import BeautifulSoup
file = open('./aa.html', 'rb')
html = file.read()
bs = BeautifulSoup(html,"html.parser")
print(type(bs.name))
print(bs.name)
print(bs.attrs)
コメント
コメントオブジェクトは特殊なタイプのNavigableStringオブジェクトであり、その出力コンテンツにはコメントシンボルが含まれていません。
from bs4 import BeautifulSoup
file = open('./aa.html', 'rb')
html = file.read()
bs = BeautifulSoup(html,"html.parser")
print(bs.a)
# 此时不能出现空格和换行符,a标签如下:
# <a class="mnav" href="http://news.baidu.com" name="tj_trnews"><!--新闻--></a>
print(bs.a.string) # 新闻
print(type(bs.a.string)) # <class 'bs4.element.Comment'>
ドキュメントツリーをトラバースする
1. .contents:Tagのすべての子ノードを取得し、リストを返します
# tag的.content 属性可以将tag的子节点以列表的方式输出
print(bs.head.contents)
# 用列表索引来获取它的某一个元素
print(bs.head.contents[1])
2.子:タグのすべての子ノードを取得し、ジェネレーターを返します
for child in bs.body.children:
print(child)
3. .descendants:タグのすべての子孫を取得します
4. .strings:タグに複数の文字列が含まれている場合、つまり子孫ノードにコンテンツがある場合は、これを使用して取得し、トラバースできます。
5. .stripped_strings:余分な空白のコンテンツを削除できることを除いて、文字列の使用法と一致します
6.親:タグの親ノードを取得します
7.親:親要素のすべてのノードを再帰的に取得し、ジェネレーターを返します
8. .previous_sibling:現在のタグの前のノードを取得します。属性は通常文字列または空白です。実際の結果は、現在のタグと前のタグの間のコンマと改行です。
9. .next_sibling:現在のタグの次のノードを取得します。属性は通常、文字列または空白です。結果は、現在のタグと次のタグの間のコンマと改行です。
10. .previous_siblings:現在のタグの上にあるすべての兄弟ノードを取得し、ジェネレーターを返します
11. .next_siblings:現在のタグの下にあるすべての兄弟ノードを取得し、ジェネレーターを返します
12. .previous_element:解析プロセスで最後に解析されたオブジェクト(文字列またはタグ)を取得します。これはprevious_siblingと同じ場合がありますが、通常は異なります。
13. Next_element:解析プロセス中に解析される次のオブジェクト(文字列またはタグ)を取得します。これはnext_siblingと同じ場合がありますが、通常は異なります。
14. .previous_elements:ドキュメントの解析されたコンテンツに前方にアクセスできるジェネレーターを返します
15. .next_elements:ドキュメントの解析されたコンテンツに逆方向にアクセスできるジェネレーターを返します
16..has_attr:タグに属性が含まれているかどうかを確認します
ドキュメントツリーを検索する
上記の栗では、find_allの使用法を簡単に紹介し、次にfind_all-filtersの使用法をさらに紹介しました。これらのフィルターは、検索API全体で実行されます。フィルターは、タグ名、ノード属性などで使用できます。
(1)名前パラメータ:
文字列フィルタリング:文字列と完全に一致するラベルのすべてのコンテンツを検索し、リストを返します
a_list = bs.find_all("a")
print(a_list)
正規表現のフィルタリング:正規表現が渡されると、BeautifulSoup4はsearch()を介してコンテンツを照合し、文字列を含むラベルのすべてのコンテンツを返し、リストを返します。
from bs4 import BeautifulSoup
import re
file = open('./aa.html', 'rb')
html = file.read()
bs = BeautifulSoup(html,"html.parser")
# 正则表达式
t_list = bs.find_all(re.compile("a"))
for item in t_list:
print(item)
bs = BeautifulSoup(html,"html.parser")
リスト:リストを渡すと、BeautifulSoup4はリスト内の任意の要素に一致するノードを返します
t_list = bs.find_all(["meta","link"])
for item in t_list:
print(item)
メソッド:メソッドを渡し、メソッドに従って照合します
from bs4 import BeautifulSoup
file = open('./aa.html', 'rb')
html = file.read()
bs = BeautifulSoup(html,"html.parser")
def name_is_exists(tag):
return tag.has_attr("name")
# 根据一个函数来获取
t_list = bs.find_all(name_is_exists)
for item in t_list:
print(item)
(2)Kwargsパラメーター:
from bs4 import BeautifulSoup
import re
file = open('./aa.html', 'rb')
html = file.read()
bs = BeautifulSoup(html,"html.parser")
# 查询id=head的Tag中的全部内容
t_list = bs.find_all(id="head")
print(t_list)
# 查询href属性包含ss1.bdstatic.com的Tag
t_list = bs.find_all(href=re.compile("http://news.baidu.com"))
print(t_list)
# 查询所有包含class的Tag(注意:class在Python中属于关键字,所以加_以示区别)
t_list = bs.find_all(class_=True)
for item in t_list:
print(item)
(3)属性パラメーター:
HTMLデータなど、すべての属性をこの方法で検索できるわけではありません-*属性:
t_list = bs.find_all(data-foo="value")
如果执行这段代码,将会报错。我们可以使用attrs参数,定义一个字典来搜索包含特殊属性的tag:
t_list = bs.find_all(attrs={
"data-foo":"value"})
for item in t_list:
print(item)
(4)テキストパラメータ:
textパラメータを使用して、ドキュメント内の文字列コンテンツを検索できます。nameパラメータのオプション値と同様に、textパラメータは文字列、正規表現、およびリストを受け入れます。
from bs4 import BeautifulSoup
import re
file = open('./aa.html', 'rb')
html = file.read()
bs = BeautifulSoup(html, "html.parser")
t_list = bs.find_all(attrs={
"data-foo": "value"})
for item in t_list:
print(item)
t_list = bs.find_all(text="hao123")
for item in t_list:
print(item)
t_list = bs.find_all(text=["hao123", "地图", "贴吧"])
for item in t_list:
print(item)
t_list = bs.find_all(text=re.compile("\d"))
for item in t_list:
print(item)
テキスト内のいくつかの特別な属性を検索するとき、目的を達成するためのメソッドを渡すこともできます。
def length_is_two(text):
return text and len(text) == 2
t_list = bs.find_all(text=length_is_two)
for item in t_list:
print(item)
(5)制限パラメータ:制限パラメータ
を渡して、返されるデータの数を制限できます。検索されるデータの量が5で、limit = 2が設定されている場合、この時点では最初の2つのデータのみが返されます。
from bs4 import BeautifulSoup
import re
file = open('./aa.html', 'rb')
html = file.read()
bs = BeautifulSoup(html, "html.parser")
t_list = bs.find_all("a",limit=2)
for item in t_list:
print(item)
上記のいくつかの従来の書き込み方法に加えて、find_allは短縮することもできます。
# 两者是相等的
# t_list = bs.find_all("a") => t_list = bs("a")
t_list = bs("a") # 两者是相等的
# t_list = bs.a.find_all(text="新闻") => t_list = bs.a(text="新闻")
t_list = bs.a(text="新闻")
6.2、find()
find()は、条件を満たす最初のタグを返します。またはタグのみが必要な場合は、find()メソッドを使用できます。もちろん、find_all()メソッドを使用してlimit = 1を渡してから、最初の値を取得することもできますが、面倒です。
from bs4 import BeautifulSoup
import re
file = open('./aa.html', 'rb')
html = file.read()
bs = BeautifulSoup(html, "html.parser")
# 返回只有一个结果的列表
t_list = bs.find_all("title",limit=1)
print(t_list)
# 返回唯一值
t = bs.find("title")
print(t)
# 如果没有找到,则返回None
t = bs.find("abc") print(t)
結果から、limit = 1が渡されても、戻り値はリストであることがわかります。値を1つだけ取得する必要がある場合は、findメソッドよりもはるかに便利ではありません。ただし、値が見つからない場合は、Noneが返されます。
上記のBeautifulSoup4を導入したとき、bs.divを介して最初のdivタグを取得できることがわかりました。最初のdivの下で最初のdivを取得する必要がある場合は、次の
ようにします。
t = bs.div.div
# 等价于
t = bs.find("div").find("div")
CSSセレクター
BeautifulSoupは部分的なCSSセレクターをサポートしています。タグの.select()メソッドに文字列パラメーターを渡してBeautifulSoupオブジェクトを取得し、CSSセレクターの構文を使用してタグを見つけることができます。
1.タグ名で検索
print(bs.select('title'))
print(bs.select('a'))
2.クラス名で検索
print(bs.select('.mnav'))
3.IDで検索
print(bs.select('#u1'))
4.組み合わせ検索
print(bs.select('div .bri'))
5.属性検索
print(bs.select('a[class="bri"]'))
print(bs.select('a[href="http://tieba.baidu.com"]'))
6.直接サブタグ検索
t_list = bs.select("head > title")
print(t_list)
7、兄弟ノードラベルルックアップ
t_list = bs.select(".mnav ~ .bri")
print(t_list)
8.コンテンツを取得する
t_list = bs.select("title")
print(bs.select('title')[0].get_text())