前のブログ2.urllibライブラリの学習、アンチクローラーWebソースコードクロールはWebソースコードをクロールする方法を紹介しました。このブログはクロールされたhtmlファイルを解析する方法を紹介しました
美しいスープを使用してhtmlファイルを解析します
1.最初にBaiduホームページにクロールし、ソースコードをローカルに保存します
import pickle # 保存html文件
import urllib.request
url = "http://www.baidu.com"
response = urllib.request.urlopen(url)
pickle.dump(response.read(),open('./baidu.html','wb'))
ある日、BaiduがBaiduでなくなった場合、このブログはフォローアップチュートリアル
2021.02.02.12の次のhtmlソースコードをダウンロードできます。57baiduホームページのソースコードをクロールします:https://wwx.lanzoui.com/i5QOvl7peyb
2.html.parserを使用して解析します
from bs4 import BeautifulSoup
file = open("./baidu.html", "rb")
html = file.read() # 读取文本
bs = BeautifulSoup(html, "html.parser") # bs对象来解析,使用html.parser解析器
bsは作成されたBeautifulSoup解析オブジェクト、bsは<class'bs4.BeautifulSoup '>のタイプ、BeautifulSoup4は複雑なHTMLドキュメントを複雑なツリー構造に変換し、各ノードはPythonオブジェクトであり、すべてのオブジェクトは4つのタイプに要約できます。
-
1.タグ
-
2.NavigableString
-
3.BeautifulSoup
-
4.コメント
1.タグ:タグ(タグのコンテンツを含む)、最初に一致するタグのみが見つかりました
print(bs.title)
print(type(bs.title))
bs.titleは最初のタイトルと一致します:
百度一下,你就知道
type(bs.title)是:<class'bs4.element.Tag '>
オブジェクトを解析します。タグを付け、タグとそのコンテンツを取得します
2. NavigableString:タグのコンテンツ
print(bs.title.string)
print(type(bs.title.string)) # NavigableString
bs.titleは最初のタイトルと一致します:
百度一下,你就知道
bs.title.stringは次のとおりです。Baiduをクリックすると、わかります
type(bs.title.string)是:<クラス 'bs4.element.NavigableString'>
オブジェクトを解析します。ラベル。文字列はラベルの中央のコンテンツです。
タグとそのコンテンツの取得、タグのコンテンツの取得に加えて、タグの属性を取得することもできます。
print(bs.a)
print(bs.a.attrs)
print(type(bs.a.attrs)) # <class 'dict'>
bs.aは:Baiduホームページ
bs.a.attrs是:{'class':['toindex']、 'href': '/'}
type(bs.a.attrs)是:<class'dict '>
object.label.attrsの解析は、ラベルのすべての属性であり(attrsは、ラベルのクラス、href、および名前を出力できます)、すべての属性のキーと値のペアを含む辞書を返します。
3. BeautifulSoup:ドキュメント全体を表します
print(bs) # 打印的就是整个文档
print(type(bs))
print(bs.name) # [document]
print(bs.a.name)
print(bs)は、htmlドキュメントのコンテンツ全体を印刷します
type(bs)是:<クラス 'bs4.BeautifulSoup'>
bs.nameは次のとおりです:[ドキュメント]
bs.a.nameは次のとおりです。
解析オブジェクト。タグ。名前はタグまたは解析オブジェクトのタイプです。名前は解析オブジェクトのタイプです。
5.コメント:特別なNavigableStringであり、出力コンテンツにはコメントが含まれていません
コメントを表示するには、 baidu.htmlのBaiduホームページを手動で変更してください。
注:再度実行するときは、クロールを続け、baidu.html部分にコードを保存してください。
print(bs.a)
print(bs.a.string)
print(type(bs.a.string)) # Comment
bs.a.stringは:Baiduホームページ
type(bs.a.string)是:<クラス 'bs4.element.Comment'>
タグ内のコンテンツに注釈が付けられている限り、分析オブジェクト.tag.stringは自動的にブロックされることがわかりました。そして、解析オブジェクト。タグ。文字列は<class'bs4.element.Comment '>のタイプになります。簡単な要約コメントはBeautifulSoupの特殊なケースです。
実用化
パーサーは、htmlソースコードをツリーのようなデータ構造に編成および管理し、トラバーサルメソッドを使用してすべてのノードを取得します
ノード取得:トラバーサル
print(bs.head.contents)
print(bs.head.contents[1])
bs.head.contentsは、headタグのすべての第1レベルのタグです。
bs.head.contents [1]は、headタグ内のすべての第1レベルタグの2番目を取得します
object.head.contentsを分析して、headタグ内のすべての第1レベルのタグを取得し、リストを使用して
ドキュメント検索:ターゲット(divを指定)
1.find_all
文字列フィルタリング。文字列と完全に一致するすべてのタグコンテンツを照合し、結果リストを返します。次に例を示します。
t_list = bs.find_all("a")
print(t_list)
すべてのタグを検索し、結果のリストを返します
2.正規表現検索:検索方法を使用してコンテンツを照合します
それでも上の栗は、文字ですべてのコンテンツを見つけます
t_list = bs.find_all(re.compile("a"))
printf(t_list)
t_list = bs.find_all(text=re.compile("\d")) # 包含数字的字符串
for it in t_list:
print(it)
re.compile( "a")は、匿名モードのオブジェクトを作成し、タグとコンテンツを探します。正規表現のパターンオブジェクトをテキストtext = re.compile( "\ d")に割り当てることもできます。検索は、数字を含むコンテンツ(ラベル自体は含まない)を検索します。
3.メソッド:関数(メソッド)を渡し、関数の要件に従って検索します
最初に、ラベルに名前属性1の真の値があるかどうかを返す関数を定義します。
def name_is_exists(tag):
return tag.has_attr("name")
t_list = bs.find_all(name_is_exists) # 查询所有有name属性的标签
print(t_list)
bs.find_all(name_is_exists)は、name属性を持つすべてのタグを検索します
4.kwargsパラメーター
t_list = bs.find_all(id="head") # id是head的标签
print(it)
t_list = bs.find_all(class_=True) # 有class属性值的标签
print(it)
t_list = bs.find_all(href="http://news.baidu.com") # 查找href="http://news.baidu.com"
print(it)
5.テキストパラメータ:特定のテキスト
「hao123」のテキストを含むコンテンツを検索する
t_list = bs.find_all(text="hao123")
# 参数可以是列表,结果是并集
t_list = bs.find_all(text=["hao123","地图","贴吧"])
for it in t_list:
print(it)
複数のテキストコンテンツを同時に照合できます
6.limitパラメーター:最初の制限一致要素を取得します
t_list = bs.find_all("a", limit=3)
for it in t_list:
print(it)
上記の例では、最初の3つのタグを取得します
7. CSSセレクター:ページにネストされ、IDまたはクラスによる高速ポジショニング、パラメーターはタグIDにすることができ、クラスの使用法はjQueryに似ています
# 按标签查找,返回所有匹配的标签
print(bs.select('title'))
# 按类名查找,返回所有匹配的标签
print(bs.select('.mnav'))
# 按id查找,返回所有匹配的标签
print(bs.select('#u1'))
# 筛选某个标签的属性或者id等于什么,返回所有匹配的标签
print(bs.select("a[class='s-set-hotsearch set-show']")) # 筛选class是's-set-hotsearch set-show'的a标签
# 通过层级结构查找子标签
res = bs.select("head > link")# 查找head标签中的所有link子标签,不包含孙标签
print(res)
print(len(res))
for it in res:
print(it)
# 查找兄弟标签,特点是只能往后查找
t_list = bs.select(".toindex ~ .pf") # 先找到class是toindex的标签,然后向后查找class是pf的同级标签
print(len(t_list))
print(t_list[0].get_text())
这个例子涉及到html源码中的如下内容
"""
<a class="toindex" href="/">百度首页</a>
<a href="javascript:;" name="tj_settingicon" class="pf">设置<i class="c-icon c-icon-triangle-down"></i></a>
<a href="https://passport.baidu.com/v2/?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F&sms=5" name="tj_login" class="lb" onclick="return false;">登录</a>
<div class="bdpfmenu"></div>
"""
タスク駆動型開発:DoubanTop250ムービーによってクロールされたデータをツリー構造データに整理します
# import bs4 #只需要使用bs4中的BeautifulSoup因此可以如下写法:
from bs4 import BeautifulSoup # 网页解析,获取数据
import urllib.request, urllib.error # 指定url,获取网页数据
def main():
# 爬取的网页
baseurl = "https://movie.douban.com/top250?start="
# # 保存的路径
savepath = ".\\豆瓣电影Top250.xls" # 使用\\表示层级目录或者在整个字符串前加r“.\豆瓣电影Top250”
savepath2Db = "movies.db"
# # 1.爬取网页
# print(askURL(baseurl))
datalist = getData(baseurl)
print(datalist)
# 爬取网页
def getData(baseurl):
datalist = []
for i in range(0, 10): # 一页25条电影
url = baseurl + str(i*25)
html = askURL(url) # 保存获取到的网页源码
# print(html)
# 2.解析数据(逐一)
soup = BeautifulSoup(html, "html.parser") # 使用html.parser解析器解析html文档形成树形结构数据
# 解析...
return datalist
# 得到执行url的网页信息
def askURL(url):
# 头部信息 其中用户代理用于伪装浏览器访问网页
head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/87.0.4280.88 Safari/537.36"}
req = urllib.request.Request(url, headers=head)
html = "" # 获取到的网页源码
try:
response = urllib.request.urlopen(req)
html = response.read().decode("utf-8")
except urllib.error.URLError as e:
if hasattr(e, "code"): # has attribute
print(e.code)
if hasattr(e, "reason"):
print(e.reason)
return html
if __name__ == '__main__':
main()
ブール値↩︎