beautifulsoup4
模块
beautifulsoup4
的简介
Beautiful Soup是一个可以从HTML或XML文件中提取数据的python库。
- 安装
beautifulsoup4
# 安装
pip install beautifulsoup4
-
解析库
BeautifulSoup默认支持Python的标准HTML解析库,但是它也支持一些第三方的解析库
序号 解析库 使用方法 优势 劣势 1 Python标准库 BeautifulSoup(html,’html.parser’) Python内置标准库;执行速度快 容错能力较差 2 lxml HTML解析库 BeautifulSoup(html,’lxml’) 速度快;容错能力强 需要安装,需要C语言库 3 lxml XML解析库 BeautifulSoup(html,[‘lxml’,’xml’]) 速度快;容错能力强;支持XML格式 需要C语言库 4 htm5lib解析库 BeautifulSoup(html,’htm5llib’) 以浏览器方式解析,最好的容错性 速度慢 -
下载解析模块lxml
# 下载解析模块lxml pip install lxml
-
使用
# 初始化一个bs4对象 import requests from bs4 import BeautifulSoup res = requests.get("https://www.mzitu.com/") soup = BeautifulSoup(res.text,'lxml') #解析的文本 解析器
案例1:爬取汽车之家的新闻
import requests
from bs4 import BeautifulSoup
res = requests.get("https://www.autohome.com.cn/news/1/#liststart")
soup = BeautifulSoup(res.text, 'lxml')
ul = soup.find(class_='article') # 查找class为article的ul
li_list = ul.find_all(name='li') # 查找ul下的所有li
new_list = []
for li in li_list:
title = li.find(name='h3') # 查找li下name=h3的tag
if title:
new_list.append({
'title': title.text,
'link': 'http:' + li.find('a').attrs.get('href'),
'abstract': li.find('p').text,
'img': 'http:' + li.find(name='img').attrs.get('src')
})
import json
with open('news.doc', mode='wb') as fw:
for item in new_list:
fw.write(json.dumps(item, ensure_ascii=False).encode('utf-8'))
fw.write('
'.encode('utf-8'))
bs4
模块的使用
<1>遍历文档树
<2>搜索文档树(5种过滤规则)
<3>limit和recursive参数
遍历文档树
(0)用法
(1)获取标签的名称
(2)获取标签的属性
(3)获取标签的内容
(4)嵌套使用
(5)子节点、子孙节点
(6)父节点、祖先节点
用法
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p id="my_p" class="title">hello<b id="bbb" class="boldest">The Dormouse's story</b>
</p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a><a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
lxml文档容错能力强,能够解析非标准html文档
# 使用方式1
soup = BeautifulSoup(html_doc,'lxml')
# print(soup.prettify())
# 使用方式2
soup = BeautifulSoup(open('a.html'),'lxml')
获取标签的名字
soup = BeautifulSoup(html_doc,'lxml')
head = soup.head
print(type(head)) # tag <class 'bs4.element.Tag'>
print(head.name) # head
获取标签的属性(重点)
p = soup.body.p # <class 'bs4.element.Tag'>
print(p.attrs) # {'id': 'my_p', 'class': ['title']}
print(p.attrs.get('id')) # my_p
print(p['id']) # my_p
print(p.get('id')) # my_p
获取标签的内容
# text会取标签子子孙孙的内容拼接在一起
p = soup.body.p
print(p.text) #helloThe Dormouse's story
# p下文本只有一个的时候取到,否则为None
print(p.string) # None
# 拿到一个生成器对象,取到p下的所有文本内容
print(p.strings) # <generator object Tag._all_strings at 0x7f02260213c0>
print(list(p.strings)) # ['hello', "The Dormouse's story", '
']
或者
for item in p.strings:
print(item)
嵌套使用
a = soup.body.a
print(a.get('id'))
子节点、子孙节点
print(soup.p.contents) # ['hello', <b class="boldest" id="bbb">The Dormouse's story</b>, '
'] 获取p下的所有子节点
print(soup.p.children) # 获取p下的子节点,是一个生成器对象 <list_iterator object at 0x7f24215e3b80>
print(list(soup.p.children)) # ['hello', <b class="boldest" id="bbb">The Dormouse's story</b>, '
']
父节点,祖先节点
# 获取p标签的父节点
print(soup.p.parent)
# a标签所有的祖先节点,父亲的父亲,父亲的父亲的父亲
print(soup.a.parents)
兄弟节点
# print(soup.a.next_sibling) #下一个兄弟
# print(soup.a.previous_sibling) #上一个兄弟
# print(list(soup.a.next_siblings)) #下面的兄弟们=>生成器对象
# print(list(soup.a.previous_siblings)) #上面的兄弟们=>生成器对象
搜索文档树
<1>find() # 只返回找到的第一个
<2>find_all() # 找到所有的
<3>5种过滤器:字符串、正则表达式、列表、True、方法
字符串过滤
# 过滤的内容是字符串
# a=soup.find(name='a')
# res=soup.find(id='my_p')
# res=soup.find(class_='story')
# res=soup.find(href='http://example.com/elsie')
# res=soup.find(attrs={'id':'my_p'})
# res=soup.find(attrs={'class':'story'})
# print(res)
正则表达式
# import re
# # re_b=re.compile('^b')
# res=soup.find(name=re_b)
# # res=soup.find_all(name=re_b)
# res=soup.find_all(id=re.compile('^l'))
# print(res)
列表
# res=soup.find_all(name=['body','b'])
# res=soup.find_all(class_=['sister','title'])
# print(res)
True
# res=soup.find_all(name=True)
# res=soup.find_all(id=True)
# res=soup.find_all(id=False)
# res=soup.find_all(href=True)
# print(res)
方法
# def has_class_but_no_id(tag):
# return tag.has_attr('class') and not tag.has_attr('id')
#
# print(soup.find_all(has_class_but_no_id))
limit(限制查找的条数)
# res=soup.find_all(name=True,limit=1)
# print(res)
# recursive(recursive递归查找,找子子孙孙)
# res=soup.body.find_all(name='b ',recursive=False)
# res=soup.body.find_all(name='p',recursive=False)
# res=soup.body.find_all(name='b',recursive=True)
# print(res)
css选择器
# ret=soup.select('#my_p')
# https://www.w3school.com.cn/cssref/css_selectors.asp
# ret=soup.select('body p') # 子子孙孙
# ret=soup.select('body>p') # 直接子节点(儿子)
# ret=soup.select('body>p')[0].text # 直接子节点(儿子)
# # ret=soup.select('body>p')[0].a.find()
# print(ret)
bs4的修改文档树 软件配置文件是xml格式的
软件的配置文件的格式:
# ini:configparser
# conf
# xml:bs4
# yaml格式