一、介绍
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间,官网推荐在现在的项目中使用Beautiful Soup 4, 移植到BS4,安装模块如下:

#pip3installbeautifulsoup4#pip3installLXML


二、用法

frombs4importBeautifulSouphtml_doc="""<html><head><title>TheDormouse'sstory</title></head><body>asdf<divclass="title"><b>TheDormouse'sstory总共</b><h2>f</h2></div><divclass="story">Onceuponatimetherewerethreelittlesisters;andtheirnameswere<aclass="sister0"id="link1">Els<span>f</span>ie</a>,<ahref="http://example.com/lacie"class="sister"id="link2">Lacie</a>and<ahref="http://example.com/tillie"class="sister"id="link3">Tillie</a>;andtheylivedatthebottomofawell.</div>ad<br/>sf<pclass="story">...</p></body></html>"""soup=BeautifulSoup(html_doc,features="lxml")tag1=soup.find(name='a')#找到第一个a标签tag2=soup.find_all(name='a')#找到所有的a标签tag3=soup.select('#link2')#找到id=link2的标签


1、标签名称查找

tag=soup.find('a')name=tag.name#获取标签名称,结果atag.name='span'#设置标签名称

2、标签属性查找

tag=soup.find('a')attrs=tag.attrs#获取名称为a的标签的属性,结果{'class':['sister0'],'id':'link1'}tag.attrs={'ik':123}#设置tag.attrs['id']='iiiii'#设置#可以使用print(soup)查看设置后的所有标签属性

3、子孙标签查找

soup.p.contents#p下所有子节点soup.p.children#得到一个迭代器,包含p下所有子节点fori,childinenumerate(soup.p.children):print(i,child)soup.p.descendants#获取子孙节点,p下所有的标签都会选择出来fori,childinenumerate(soup.p.descendants):print(i,child)

4、clear,将标签的所有子标签全部清空(保留标签名)

tag=soup.find('body')tag.clear()#清空名称为body的标签,保留标签名

5、decompose,递归的删除所有的标签

body=soup.find('body')body.decompose()#递归的删除名称为body的标签

6、extract,递归的删除所有的标签,并获取删除的标签

body=soup.find('body')v=body.extract()#递归的删除名称为body的标签print(soup)#查看删除后的结果为<html><head><title>TheDormouse'sstory</title></head></html>

7、decode,转换为字符串(含当前标签);decode_contents(不含当前标签)

body=soup.find('body')print(body.decode())#名称为body的标签转换为字符串,包含body标签print(body.decode_contents())#名称为body的标签转换为字符串,不包含body标签

8、 encode,转换为字节(含当前标签);encode_contents(不含当前标签)

body=soup.find('body')print(body.encode())#名称为body的标签转换为字节,包含body标签print(body.encode_contents())#名称为body的标签转换为字节,不包含body标签


9、find,获取匹配的第一个标签

soup.find_all('title',limit=1)soup.find('title')#上面两个查找结果一样,find查找就相当于find_all查找并设置limit=1#find_all()方法的返回结果是值包含一个元素的列表,而find()方法直接返回结果.#find_all()方法没有找到目标是返回空列表,find()方法找不到目标时,返回Nonesoup.find("head").find("title")#可以简单写成soup.head.titletag=soup.find(name='a',attrs={'class':'sister'},recursive=True,text='Lacie')tag=soup.find(name='a',class_='sister',recursive=True,text='Lacie')

10、find_all,获取匹配的所有标签

#######列表#######v=soup.find_all(name=['a','div'])print(v)v=soup.find_all(class_=['sister0','sister'])print(v)v=soup.find_all(text=['Tillie'])print(v,type(v[0]))#结果:['Tillie']<class'bs4.element.NavigableString'>v=soup.find_all(id=['link1','link2'])#查找id为link1,link2的标签,结果放在列表里面print(v)v=soup.find_all(href=['link1','link2'])#没找到href为link1,link2的标签,所以结果是一个空列表print(v)#######正则#######importrerep=re.compile('p')#匹配规则为p标签rep=re.compile('^p')#匹配规则为p开头标签v=soup.find_all(name=rep)#找p开头的的所有标签rep=re.compile('sister.*')v=soup.find_all(class_=rep)v=soup.find_all(attrs={"class":rep})#和上面的一样rep=re.compile('http://www.oldboy.com/static/.*')v=soup.find_all(href=rep)#匹配#######方法筛选#######deffunc(tag):returntag.has_attr('class')andtag.has_attr('id')v=soup.find_all(name=func)print(v)get,获取标签属性tag=soup.find('a')v=tag.get('id')#获取标签名称为a的id属性print(v)

11、has_attr,检查标签是否具有该属性

tag=soup.find('a')v=tag.has_attr('id')#检查标签a是否具有id属性print(v)

12、get_text,获取标签内部文本内容

tag=soup.find('a')print(tag)#<aclass="sister0"id="link1">Els<span>f</span>ie</a>v=tag.get_text('id')print(v)#结果是:Elsidfidie

13、index,检查标签在某标签中的索引位置

tag=soup.find('body')v=tag.index(tag.find('div'))print(v)tag=soup.find('body')fori,vinenumerate(tag):print(i,v)


14、is_empty_element,是否是空标签(是否可以是空)或者自闭合标签

#判断是否是如下标签:'br','hr','input','img','meta','spacer','link','frame','base'tag=soup.find('br')v=tag.is_empty_elementprint(v)

15、关联标签

soup.nextsoup.next_element#不分层次的查找标签的下一个节点soup.next_elementssoup.next_sibling#下一个兄弟soup.next_siblings#下面的兄弟们=>生成器对象tag.previoustag.previous_element#不分层次的查找标签的上一个节点tag.previous_elementstag.previous_sibling#上一个兄弟tag.previous_siblings#上面的兄弟们=>生成器对象tag.parent#获取标签的父节点tag.parents#找到标签所有的祖先节点

16、查找某标签的关联标签

tag.find_next(...)tag.find_all_next(...)tag.find_next_sibling(...)tag.find_next_siblings(...)tag.find_previous(...)tag.find_all_previous(...)tag.find_previous_sibling(...)tag.find_previous_siblings(...)tag.find_parent(...)tag.find_parents(...)#参数同find_all

17、select,select_one, CSS选择器

soup.select("title")#[<title>TheDormouse'sstory</title>]soup.select("p:nth-of-type(3)")#选择所有p标签中的第三个标签,相当于soup.select(p)[2]soup.select("bodya")#body里的a标签,结果放在列表显示soup.select("htmlheadtitle")#[<title>TheDormouse'sstory</title>]soup.select("span,a")#选择所有的span和a标签soup.select("head>title")#选择head标签下的直接title子标签soup.select("p>a")#选择p标签下的直接a子标签soup.select("p>a:nth-of-type(2)")soup.select("p>#link1")#选择p标签下的直接id为link1子标签soup.select("body>a")#选择body标签下的直接a子标签soup.select("#link1~.sister")#选择id=link1后的class=sister所有兄弟节点标签soup.select("#link1+.sister")#选择id=link1后的class=sister下一个兄弟节点标签,结果[<aclass="sister"href="http://example.com/lacie"id="link2">Lacie</a>]soup.select(".sister")#选择class为sister的标签soup.select("[class~=sister]")#class=sister的所有节点soup.select("#link1")#选择id为link1的标签soup.select("a#link2")#a节点,且id=link2的节点soup.select('a[href]')#所有的a节点,有href属性soup.select('a[href="http://example.com/elsie"]')#指定href属性值的所有a节点soup.select('a[href^="http://example.com/"]')soup.select('a[href$="tillie"]')#href属性以指定值结尾的所有a节点soup.select('a[href*=".com/el"]')frombs4.elementimportTagdefdefault_candidate_generator(tag):forchildintag.descendants:ifnotisinstance(child,Tag):continueifnotchild.has_attr('href'):continueyieldchildtags=soup.find('body').select("a",_candidate_generator=default_candidate_generator)print(type(tags),tags)#结果:<class'list'>[<aclass="sister"href="http://example.com/lacie"id="link2">Lacie</a>,<aclass="sister"href="http://example.com/tillie"id="link3">Tillie</a>]frombs4.elementimportTagdefdefault_candidate_generator(tag):forchildintag.descendants:ifnotisinstance(child,Tag):continueifnotchild.has_attr('href'):continueyieldchildtags=soup.find('body').select("a",_candidate_generator=default_candidate_generator,limit=1)print(type(tags),tags)#结果:<class'list'>[<aclass="sister"href="http://example.com/lacie"id="link2">Lacie</a>]

18、标签的内容

tag=soup.find('span')print(tag.string)#获取,结果ftag.string='newcontent'#设置span标签内容为newcontenttag=soup.find('body')print(tag.string)#结果Nonetag.string='xxx'#<body>xxx</body>tag=soup.find('body')v=tag.stripped_strings#递归内部获取所有标签的文本print(v)#<generatorobjectstripped_stringsat0x00000000021B0360>

19、append在当前标签内部追加一个标签

tag=soup.find('body')tag.append(soup.find('a'))#在body标签里追加<aclass="sister0"id="link1">Els<span>f</span>ie</a>frombs4.elementimportTagobj=Tag(name='i',attrs={'id':'it'})obj.string='我是一个新来的'tag=soup.find('body')tag.append(obj)#在body标签里追加<iid="it">我是一个新来的</i>

20、insert在当前标签内部指定位置插入一个标签

frombs4.elementimportTagobj=Tag(name='i',attrs={'id':'it'})obj.string='我是一个新来的'tag=soup.find('body')tag.insert(3,obj)print(soup)

21、insert_after,insert_before 在当前标签后面或前面插入

frombs4.elementimportTagobj=Tag(name='i',attrs={'id':'it'})obj.string='我是一个新来的'tag=soup.find('body')#tag.insert_before(obj)#在当前标签前面插入tag.insert_after(obj)#在当前标签后面插入print(soup)

22、replace_with 在当前标签替换为指定标签

frombs4.elementimportTagobj=Tag(name='i',attrs={'id':'it'})obj.string='我是一个新来的'tag=soup.find('div')tag.replace_with(obj)print(soup)

23、创建标签之间的关系

tag=soup.find('div')a=soup.find('a')tag.setup(previous_sibling=a)print(tag.previous_sibling)#tag的上一个兄弟标签<aclass="sister0"id="link1">Els<span>f</span>ie</a>

24、wrap,将指定标签把当前标签包裹起来

frombs4.elementimportTagobj1=Tag(name='div',attrs={'id':'it'})obj1.string='我是一个新来的'#得到新标签<divid="it">我是一个新来的</div>tag=soup.find('a')v=tag.wrap(obj1)#<divid="it">我是一个新来的<aclass="sister0"id="link1">Els<span>f</span>ie</a></div>print(soup)tag=soup.find('a')v=tag.wrap(soup.find('p'))#p标签包住a标签<pclass="story">...<aclass="sister0"id="link1">Els<span>f</span>ie</a></p>print(soup)

25、unwrap,去掉当前标签,将保留其包裹的标签

tag=soup.find('a')v=tag.unwrap()#结果:Els<span>f</span>ieprint(soup)