单屏网站设计,团购网站 如何做推广,山西seo顾问,网站建设三网合一Python3 爬虫学习笔记第八章 —— 【解析库 Beautiful Soup】文章目录【8.1】关于 Beautiful Soup【8.2】Beautiful Soup 的基本使用【8.3】节点选择器【8.3.1】元素选择【8.3.2】提取信息【8.3.3】嵌套选择【8.3.4】关联选择【8.4】方法选择器【8.4.1】find_all() 方法【8.4.2… Python3 爬虫学习笔记第八章 —— 【解析库 Beautiful Soup】 文章目录【8.1】关于 Beautiful Soup【8.2】Beautiful Soup 的基本使用【8.3】节点选择器【8.3.1】元素选择【8.3.2】提取信息【8.3.3】嵌套选择【8.3.4】关联选择【8.4】方法选择器【8.4.1】find_all() 方法【8.4.2】find() 方法【8.5】CSS 选择器【8.6】附表Beautiful Soup 库 soup 对象常用属性与方法【8.1】关于 Beautiful Soup
Beautiful Soup 可以从 HTML 或者 XML 文件中提取数据Beautiful Soup 可以提供一些简单的、Python 式的函数用来处理导航、搜索、修改分析树等它借助网页的结构和属性等特性来解析网页lxml 只会局部遍历而 Beautiful Soup 是基于 HTML DOM 的会载入整个文档解析整个 DOM 树因此时间和内存开销都会大很多所以性能要低于lxml
抓取工具速度使用难度安装难度正则最快困难无内置lxml快简单一般BeautifulSoup慢最简单简单
【8.2】Beautiful Soup 的基本使用
需要使用命令 pip install bs4 安装库Beautiful Soup 在解析时依赖解析器除了支持 Python 标准库中的 HTML 解析器外还支持一些第三方解析器
解析器使用方法优势劣势Python 标准库BeautifulSoup(markup, “html.parser”)Python 的内置标准库、执行速度适中 、文档容错能力强Python 2.7.3 or 3.2.2) 前的版本中文容错能力差LXML HTML 解析器BeautifulSoup(markup, “lxml”)速度快、文档容错能力强需要安装 C 语言库LXML XML 解析器BeautifulSoup(markup, “xml”)速度快、唯一支持 XML 的解析器需要安装 C 语言库html5libBeautifulSoup(markup, “html5lib”)最好的容错性、以浏览器的方式解析文档、生成 HTML5 格式的文档速度慢、不依赖外部扩展
基本使用
from bs4 import BeautifulSoup
soup BeautifulSoup(pHello/p, lxml)
# soup BeautifulSoup(open(soup.html, encodingutf8), lxml)
print(soup.p.string)输出结果
Hello【8.3】节点选择器
直接调用节点的名称就可以选择节点元素再调用 string 属性就可以得到节点内的文本
【8.3.1】元素选择
新建 soup.html 文件
!DOCTYPE html
html langen
headmeta charsetUTF-8 /title测试bs4/title
/head
body
div甄姬p百里守约/pp李白/p太乙真人
/div
div classsongp李清照/pp王安石/pp苏轼/pp柳宗元/pa hrefhttp://www.song.com/ title赵匡义 target_self宋朝是最强大的王朝不是军队的强大而是经济很强大国民都很有钱。/aimg srchttp://www.baidu.com/meinv.jpg alta href classdu总为浮云能蔽日长安不见使人愁/a
/div
div classtangullia hrefhttp://www.baidu.com titleqing清明时节雨纷纷路上行人欲断魂借问酒家何处有牧童遥指杏花村。/a /lilia hrefhttp://www.163.com titleqin秦时明月汉时关万里长征人未还但使龙城飞将在不教胡马度阴山。/a /lilia hrefhttp://www.126.com altqi岐王宅里寻常见崔九堂前几度闻正是江南好风景落花时节又逢君。/a /lilia hrefhttp://www.sina.com classdu杜甫/a /lilib唐朝/b/lilii宋朝/i/lilia hrefhttp://www.haha.com idfeng凤凰台上凤凰游凤去台空江自流吴宫花草埋幽径晋代衣冠成古丘。/a /li/ul
/div/body
/htmlfrom bs4 import BeautifulSoup
soup BeautifulSoup(open(soup.html, encodingutf8), lxml)
print(soup.title)
print(type(soup.title))
print(soup.title.string)
print(soup.head)
print(soup.p)依次查找 title、head、p 节点。输出结果
title测试bs4/title
class bs4.element.Tag
测试bs4
head
meta charsetutf-8/
title测试bs4/title
/head
p百里守约/p【8.3.2】提取信息
string 属性获取节点包含的文本值如果标签里面还有标签那么string获取到的结果为Nonetext 属性获取节点包含的文本值get_text() 属性获取节点包含的文本值name 属性获取节点的名称attrs 获取所有属性attrs[‘属性名’] 获取指定属性
依然以 soup.html 为例
from bs4 import BeautifulSoup
soup BeautifulSoup(open(soup.html, encodingutf8), lxml)
print(soup.title)
print(soup.title.text)
print(soup.title.get_text())
print(soup.title.string)
print(soup.div.string)
print(soup.div.text)
print(soup.title.name)
print(soup.a[href]) # 获取href属性
print(soup.a[title]) # 获取title属性
print(soup.a[target]) # 获取target属性
print(soup.a.attrs) # 获取所有属性
print(soup.a.attrs[href]) # 获取href属性输出结果
title测试bs4/title
测试bs4
测试bs4
测试bs4
None甄姬百里守约
李白太乙真人title
http://www.song.com/
赵匡义
_self
{href: http://www.song.com/, title: 赵匡义, target: _self}
http://www.song.com/【8.3.3】嵌套选择
from bs4 import BeautifulSouphtml
htmlheadtitleThis is a demo/title/head
bodysoup BeautifulSoup(html, lxml)
print(soup.head.title)
print(type(soup.head.title))
print(soup.head.title.string)获取 head 节点里面的 title 节点输出结果
titleThis is a demo/title
class bs4.element.Tag
This is a demo【8.3.4】关联选择
contents 属性获取某个节点元素的直接子节点children 属性遍历某个节点元素的子节点descendants 属性获取某个节点元素所有的子孙节点parent 属性获取某个节点元素的父节点parents 属性获取某个节点元素所有的祖先节点next_sibling 属性获取节点的下一个兄弟元素previous_sibling 属性获取节点的上一个兄弟元素next_siblings 属性获取某个节点所有后面的兄弟元素previous_siblings 属性获取某个节点所有前面的兄弟元素
contents 属性应用示例
from bs4 import BeautifulSouphtml
htmlheadtitleThe Dormouses story/title/headbodyp classstoryOnce upon a time there were three little sisters; and their names werea hrefhttp://example.com/elsie classsister idlink1spanElsie/span/aa hrefhttp://example.com/lacie classsister idlink2Lacie/a anda hrefhttp://example.com/tillie classsister idlink3Tillie/aand they lived at the bottom of a well./pp classstory.../psoup BeautifulSoup(html, lxml)
print(soup.p.contents)获取 p 节点元素的直接子节点输出结果
[\n Once upon a time there were three little sisters; and their names were\n , a classsister hrefhttp://example.com/elsie idlink1
spanElsie/span
/a, \n, a classsister hrefhttp://example.com/lacie idlink2Lacie/a, \n and\n , a classsister hrefhttp://example.com/tillie idlink3Tillie/a, \n and they lived at the bottom of a well.\n ]children 属性应用示例
from bs4 import BeautifulSouphtml
htmlheadtitleThe Dormouses story/title/headbodyp classstoryOnce upon a time there were three little sisters; and their names werea hrefhttp://example.com/elsie classsister idlink1spanElsie/span/aa hrefhttp://example.com/lacie classsister idlink2Lacie/a anda hrefhttp://example.com/tillie classsister idlink3Tillie/aand they lived at the bottom of a well./pp classstory.../psoup BeautifulSoup(html, lxml)
print(soup.p.children)
for i, child in enumerate(soup.p.children):print(i, child)遍历 p 节点元素的子节点输出结果
list_iterator object at 0x00000228E3C205F8
0 Once upon a time there were three little sisters; and their names were1 a classsister hrefhttp://example.com/elsie idlink1
spanElsie/span
/a
2 3 a classsister hrefhttp://example.com/lacie idlink2Lacie/a
4 and5 a classsister hrefhttp://example.com/tillie idlink3Tillie/a
6 and they lived at the bottom of a well.descendants 属性应用示例
from bs4 import BeautifulSouphtml
htmlheadtitleThe Dormouses story/title/headbodyp classstoryOnce upon a time there were three little sisters; and their names werea hrefhttp://example.com/elsie classsister idlink1spanElsie/span/aa hrefhttp://example.com/lacie classsister idlink2Lacie/a anda hrefhttp://example.com/tillie classsister idlink3Tillie/aand they lived at the bottom of a well./pp classstory.../psoup BeautifulSoup(html, lxml)
print(soup.p.descendants)
for i, child in enumerate(soup.p.descendants):print(i, child)获取 p 节点元素所有的子孙节点输出结果
generator object descendants at 0x0000018404A4C3B8
0 Once upon a time there were three little sisters; and their names were1 a classsister hrefhttp://example.com/elsie idlink1
spanElsie/span
/a
2 3 spanElsie/span
4 Elsie
5 6 7 a classsister hrefhttp://example.com/lacie idlink2Lacie/a
8 Lacie
9 and10 a classsister hrefhttp://example.com/tillie idlink3Tillie/a
11 Tillie
12 and they lived at the bottom of a well.parent 属性应用示例
from bs4 import BeautifulSoup
html
htmlheadtitleThe Dormouses story/title/headbodyp classstoryOnce upon a time there were three little sisters; and their names werea hrefhttp://example.com/elsie classsister idlink1spanElsie/span/a/p/body
/htmlsoup BeautifulSoup(html, lxml)
print(soup.a.parent)获取 a 节点元素的父节点输出结果
p classstoryOnce upon a time there were three little sisters; and their names werea classsister hrefhttp://example.com/elsie idlink1
spanElsie/span
/a
/pparents 属性应用示例
from bs4 import BeautifulSouphtml
htmlbodyp classstorya hrefhttp://example.com/elsie classsister idlink1spanElsie/span/a/psoup BeautifulSoup(html, lxml)
print(type(soup.a.parents))
print(list(enumerate(soup.a.parents)))获取 a 节点元素所有的祖先节点输出结果
class generator
[(0, p classstory
a classsister hrefhttp://example.com/elsie idlink1
spanElsie/span
/a
/p), (1, body
p classstory
a classsister hrefhttp://example.com/elsie idlink1
spanElsie/span
/a
/p
/body), (2, html
body
p classstory
a classsister hrefhttp://example.com/elsie idlink1
spanElsie/span
/a
/p
/body/html), (3, html
body
p classstory
a classsister hrefhttp://example.com/elsie idlink1
spanElsie/span
/a
/p
/body/html)]next_sibling、previous_sibling、next_siblings、previous_siblings 属性应用示例
html
htmlbodyp classstoryOnce upon a time there were three little sisters; and their names werea hrefhttp://example.com/elsie classsister idlink1spanElsie/span/aHelloa hrefhttp://example.com/lacie classsister idlink2Lacie/a anda hrefhttp://example.com/tillie classsister idlink3Tillie/aand they lived at the bottom of a well./p /body
/htmlfrom bs4 import BeautifulSoup
soup BeautifulSoup(html, lxml)
print(Next Sibling, soup.a.next_sibling)
print(Prev Sibling, soup.a.previous_sibling)
print(Next Siblings, list(enumerate(soup.a.next_siblings)))
print(Prev Siblings, list(enumerate(soup.a.previous_siblings)))next_sibling 和 previous_sibling 分别获取 a 节点的下一个和上一个兄弟元素next_siblings 和 previous_siblings 则分别返回 a 节点后面和前面的兄弟节点输出结果
Next Sibling HelloPrev Sibling Once upon a time there were three little sisters; and their names wereNext Siblings [(0, \n Hello\n ), (1, a classsister hrefhttp://example.com/lacie idlink2Lacie/a), (2, \n and\n ), (3, a classsister hrefhttp://example.com/tillie idlink3Tillie/a), (4, \n and they lived at the bottom of a well.\n )]
Prev Siblings [(0, \n Once upon a time there were three little sisters; and their names were\n )]【8.4】方法选择器
节点选择器直接调用节点的名称就可以选择节点元素如果进行比较复杂的选择的话方法选择器是一个不错的选择它更灵活常见的方法有 find_all、find 等调用它们直接传入相应的参数就可以灵活查询了。
【8.4.1】find_all() 方法
find_all 方法可以查询所有符合条件的元素给它传入一些属性或文本来得到符合条件的元素。find_all 方法的 APIfind_all(name , attrs , recursive , text , **kwargs) 新建 soup.html
!DOCTYPE html
html langen
headmeta charsetUTF-8 /title测试bs4/title
/head
body
div甄姬p百里守约/pp李白/p太乙真人
/div
div classsongp李清照/pp王安石/pp苏轼/pp柳宗元/pa hrefhttp://www.song.com/ title赵匡义 target_self宋朝是最强大的王朝不是军队的强大而是经济很强大国民都很有钱。/aimg srchttp://www.baidu.com/meinv.jpg alta href classdu总为浮云能蔽日长安不见使人愁/a
/div
div classtangullia hrefhttp://www.baidu.com titleqing清明时节雨纷纷路上行人欲断魂借问酒家何处有牧童遥指杏花村。/a /lilia hrefhttp://www.163.com titleqin秦时明月汉时关万里长征人未还但使龙城飞将在不教胡马度阴山。/a /lilia hrefhttp://www.126.com nameqi岐王宅里寻常见崔九堂前几度闻正是江南好风景落花时节又逢君。/a /lilia hrefhttp://www.sina.com classdu杜甫/a /lilib唐朝/b/lilii宋朝/i/lilia hrefhttp://www.haha.com idfeng凤凰台上凤凰游凤去台空江自流吴宫花草埋幽径晋代衣冠成古丘。/a /li/ul
/div/body
/html示例代码
from bs4 import BeautifulSoupsoup BeautifulSoup(open(soup.html, encodingutf8), lxml)
print(soup.find_all(a), \n)
print(soup.find_all(a)[1], \n)
print(soup.find_all(a)[1].text, \n)
print(soup.find_all([a, b, i]), \n)
print(soup.find_all(a, limit2), \n)
print(soup.find_all(titleqing), \n)
print(soup.find_all(attrs{id: feng}), \n)输出结果
[a hrefhttp://www.song.com/ target_self title赵匡义宋朝是最强大的王朝不是军队的强大而是经济很强大国民都很有钱。/a, a classdu href总为浮云能蔽日长安不见使人愁/a, a hrefhttp://www.baidu.com titleqing清明时节雨纷纷路上行人欲断魂借问酒家何处有牧童遥指杏花村。/a, a hrefhttp://www.163.com titleqin秦时明月汉时关万里长征人未还但使龙城飞将在不教胡马度阴山。/a, a hrefhttp://www.126.com nameqi岐王宅里寻常见崔九堂前几度闻正是江南好风景落花时节又逢君。/a, a classdu hrefhttp://www.sina.com杜甫/a, a hrefhttp://www.haha.com idfeng凤凰台上凤凰游凤去台空江自流吴宫花草埋幽径晋代衣冠成古丘。/a] a classdu href总为浮云能蔽日长安不见使人愁/a 总为浮云能蔽日长安不见使人愁 [a hrefhttp://www.song.com/ target_self title赵匡义宋朝是最强大的王朝不是军队的强大而是经济很强大国民都很有钱。/a, a classdu href总为浮云能蔽日长安不见使人愁/a, a hrefhttp://www.baidu.com titleqing清明时节雨纷纷路上行人欲断魂借问酒家何处有牧童遥指杏花村。/a, a hrefhttp://www.163.com titleqin秦时明月汉时关万里长征人未还但使龙城飞将在不教胡马度阴山。/a, a hrefhttp://www.126.com nameqi岐王宅里寻常见崔九堂前几度闻正是江南好风景落花时节又逢君。/a, a classdu hrefhttp://www.sina.com杜甫/a, b唐朝/b, i宋朝/i, a hrefhttp://www.haha.com idfeng凤凰台上凤凰游凤去台空江自流吴宫花草埋幽径晋代衣冠成古丘。/a] [a hrefhttp://www.song.com/ target_self title赵匡义宋朝是最强大的王朝不是军队的强大而是经济很强大国民都很有钱。/a, a classdu href总为浮云能蔽日长安不见使人愁/a] [a hrefhttp://www.baidu.com titleqing清明时节雨纷纷路上行人欲断魂借问酒家何处有牧童遥指杏花村。/a] [a hrefhttp://www.haha.com idfeng凤凰台上凤凰游凤去台空江自流吴宫花草埋幽径晋代衣冠成古丘。/a] 【8.4.2】find() 方法
find() 方法使用方法与 find_all() 方法相同不同的是find 方法返回的是单个元素也就是第一个匹配的元素而 find_all 返回的是所有匹配的元素组成的列表 特别的 find_parents 和 find_parent前者返回所有祖先节点后者返回直接父节点。 find_next_siblings 和 find_next_sibling前者返回后面所有的兄弟节点后者返回后面第一个兄弟节点。 find_previous_siblings 和 find_previous_sibling前者返回前面所有的兄弟节点后者返回前面第一个兄弟节点。 find_all_next 和 find_next前者返回节点后所有符合条件的节点后者返回第一个符合条件的节点。 find_all_previous 和 find_previous前者返回节点前所有符合条件的节点后者返回第一个符合条件的节点。
【8.5】CSS 选择器
使用 CSS 选择器只需要调用 select 方法传入相应的 CSS 选择器即可 新建 soup.html 文件
!DOCTYPE html
html langen
div classtangullia hrefhttp://www.baidu.com titleqing清明时节雨纷纷路上行人欲断魂借问酒家何处有牧童遥指杏花村。/a /lilia hrefhttp://www.163.com titleqin秦时明月汉时关万里长征人未还但使龙城飞将在不教胡马度阴山。/a /lilia hrefhttp://www.126.com nameqi岐王宅里寻常见崔九堂前几度闻正是江南好风景落花时节又逢君。/a /lilia hrefhttp://www.sina.com classdu杜甫/a /lilia hrefhttp://www.haha.com idfeng凤凰台上凤凰游凤去台空江自流吴宫花草埋幽径晋代衣冠成古丘。/a /li/ul
/div/body
/html通过 CSS 选择器依次选择 class“tang” 的 div 节点下的 a 节点、id 为 feng 的节点以及其 href 元素
from bs4 import BeautifulSoupsoup BeautifulSoup(open(soup.html, encodingutf8), lxml)
print(soup.select(li), \n)
print(soup.select(.tang ul li a)[2], \n)
print(soup.select(#feng)[0].text, \n)
print(soup.select(#feng)[0][href], \n)输出结果
[lia hrefhttp://www.baidu.com titleqing清明时节雨纷纷路上行人欲断魂借问酒家何处有牧童遥指杏花村。/a /li, lia hrefhttp://www.163.com titleqin秦时明月汉时关万里长征人未还但使龙城飞将在不教胡马度阴山。/a /li, lia hrefhttp://www.126.com nameqi岐王宅里寻常见崔九堂前几度闻正是江南好风景落花时节又逢君。/a /li, lia classdu hrefhttp://www.sina.com杜甫/a /li, lia hrefhttp://www.haha.com idfeng凤凰台上凤凰游凤去台空江自流吴宫花草埋幽径晋代衣冠成古丘。/a /li] a hrefhttp://www.126.com nameqi岐王宅里寻常见崔九堂前几度闻正是江南好风景落花时节又逢君。/a 凤凰台上凤凰游凤去台空江自流吴宫花草埋幽径晋代衣冠成古丘。 http://www.haha.com 附表CSS 选择器来源https://www.w3school.com.cn/cssref/css_selectors.asp “CSS” 列指示该属性是在哪个 CSS 版本中定义的。CSS1、CSS2 还是 CSS3。
选择器例子例子描述CSS.class.intro选择 class“intro” 的所有元素1#id#firstname选择 id“firstname” 的所有元素1**选择所有元素2elementp选择所有 元素1element,elementdiv,p选择所有 元素和所有 元素1element elementdiv p选择 元素内部的所有 元素1elementelementdivp选择父元素为 元素的所有 元素2elementelementdivp选择紧接在 元素之后的所有 元素2[attribute][target]选择带有 target 属性所有元素2[attributevalue][target_blank]选择 target_blank 的所有元素2[attribute~value][title~flower]选择 title 属性包含单词 “flower” 的所有元素2[attributevalue][langen]:linka:link选择所有未被访问的链接1:visiteda:visited选择所有已被访问的链接1:activea:active选择活动链接1:hovera:hover选择鼠标指针位于其上的链接1:focusinput:focus选择获得焦点的 input 元素2:first-letterp:first-letter选择每个 元素的首字母1:first-linep:first-line选择每个 元素的首行1:first-childp:first-child选择属于父元素的第一个子元素的每个 元素2:beforep:before在每个 元素的内容之前插入内容2:afterp:after在每个 元素的内容之后插入内容2:lang(language)p:lang(it)选择带有以 “it” 开头的 lang 属性值的每个 元素2element1~element2p~ul选择前面有 元素的每个 元素3[attribute^value]a[src^“https”]选择其 src 属性值以 “https” 开头的每个 元素3[attribute$value]a[src$.pdf]选择其 src 属性以 “.pdf” 结尾的所有 元素3[attribute*value]a[src*“abc”]选择其 src 属性中包含 “abc” 子串的每个 元素3:first-of-typep:first-of-type选择属于其父元素的首个 元素的每个 元素3:last-of-typep:last-of-type选择属于其父元素的最后 元素的每个 元素3:only-of-typep:only-of-type选择属于其父元素唯一的 元素的每个 元素3:only-childp:only-child选择属于其父元素的唯一子元素的每个 元素3:nth-child(n)p:nth-child(2)选择属于其父元素的第二个子元素的每个 元素3:nth-last-child(n)p:nth-last-child(2)同上从最后一个子元素开始计数3:nth-of-type(n)p:nth-of-type(2)选择属于其父元素第二个 元素的每个 元素3:nth-last-of-type(n)p:nth-last-of-type(2)同上但是从最后一个子元素开始计数3:last-childp:last-child选择属于其父元素最后一个子元素每个 元素3:root:root选择文档的根元素3:emptyp:empty选择没有子元素的每个 元素包括文本节点3:target#news:target选择当前活动的 #news 元素3:enabledinput:enabled选择每个启用的 元素3:disabledinput:disabled选择每个禁用的 元素3:checkedinput:checked选择每个被选中的 元素3:not(selector):not§选择非 元素的每个元素3::selection::selection选择被用户选取的元素部分3
【8.6】附表Beautiful Soup 库 soup 对象常用属性与方法
基本元素说明返回类型tagsoup.abs4.element.Tagnamesoup.a.namestrattrssoup.a.attrsdictcontents子节点listchildren遍历子节点list_iteratordescendants遍历所有子孙节点generatorparent返回父亲标签bs4.element.Tagparents上行遍历父辈标签generatorprettify()添加/nstrfind_all(name,attr)soup.find_all(‘a’)/([‘a’,‘b’])/(True)/(‘p’,‘course’)/(id‘link1’)/(string‘python’)bs4.element.ResultSetfind()soup.find(‘a’)/返回第一个a标签bs4.element.Tag