安装bs4库
pip --default-timeout=100 install bs4 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
request和BeautifulSoup组合使用
from bs4 import BeautifulSoup #导入BeautifulSoup包
import requests
headers = {'User-Agent' : 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19'}
response = requests.get("http://www.baidu.com",headers=headers)
text = response.text
# 使用BeautifulSoup使用html.parser解析器解析网页的源码
soup = BeautifulSoup(text,'html.parser')
print(soup)
BeautifulSoup语法
解析器
BeautifulSoup(html, "html.parser")
BeautifulSoup(html, "lxml")
BeautifulSoup(html, "xml")
BeautifulSoup(html, "html5lib")
获取并操作单个标签
html = ''
with open('./webPage.txt','r',encoding='utf8') as f:
html = f.read() #取返回的第一个内容
s = BeautifulSoup(html, "html.parser")
获取标签
#name:标签名 ,attrs:属性名 ,text:对内容应用,正则规则 返回查找到的第一个数据
find(name,attrs,recursive,text,**wargs)
#通过标签名
lis = s.find(name='ul')
lis = s.find('ul')
#通过标签内容
tag = s.find(text='plants').parent
#利用正则,内容包含 'gae'字符
lis = s.find(text=re.compile('gae')).parent
#通过标签的属性名
lis = s.find(class_="name")
lis = s.find(attrs={'id':'producers'})
获取标签文本信息
#返回标签内的所有内容,连接成一个字符串
st = s.div.get_text()
st = s.div.text
#去除获空格和回车换行符,之后使用 '&'连接字符串
st = s.div.get_text('&',strip=True)
获取父标签
#返回标签的上一层的标签
t = s.div.div.div.parent
#返回一个所有父节点的迭代器
t = s.div.div.parents
for p in t:
print(p.text) #访问属性
获取标签属性信息
#以字典的形式返回第一个标签的所有属性
dic = s.div.attrs
#返回第一个标签的'id'属性的内容,如果不存在'id'属性会抛出异常
strs = s.div.a['id']
#获取第一个div的id属性的信息
dic = s.div.attrs['id']
其他
#将第一个找到的a标签下数内容和子节点打包成list
lis = s.a.contents
#使源码格式化
h= s.prettify()
获取多个多个标签
使用find_all方法
find_all(name,attrs,recursive,text,limit,**kwargs)
#find()也就是当limit=1
#通过标签名
lis = s.find_all('li')
#查找h1标签和a标签,可能存在包含关系
lis = s.find_all(['li','ul'])
#利用正则,查找标签包含 'l' 的标签
lis = s.find_all(re.compile(r'l'))
#通标签属性名
lis = s.find_all(attrs={'class':'name'})
lis = s.find_all(class_='name')
#通过标签内容
lis = s.find_all(text='t')
lis = s.find_all(text=re.compile('t'))
使用select方法
#层级筛选(' ':忽略层级匹配 ; '>':逐层匹配);返回的结果都放在list里面。
select(self, selector, namespaces=None, limit=None, **kwargs)
匹配字符串中符号的含义
. 后面接类名
# 后面接ID名
* 表示任意元素
使用符号
#class属性为'name'查找
lis = s.select('.name')
#div的class属性为'name'查找
lis = s.select('div.name')
#通过 id 进行查找
lis = s.select('#tertiaryconsumers')
标签匹配
# 使用空格可以跨层匹配
lis = s.select('div b')
# 逐层选择
lis = s.select('div > b')
#获取匹配的第一个
lis = s.select_one('title')
lis = s.select("title",limit=1)
#取匹配标签的第一个(从1开始计数),返回的是list
lis = s.select('ul:nth-of-type(1)')
# 通过标签
#表示先查找div 再查找li 然后放到一个list里面
lis = s.select('div,li')
lis = s.select('ul')[0].string
#取匹配标签的第一个(从1开始计数),返回的是list
lis = s.select('ul:nth-of-type(1)')
#匹配 ul 兄弟节点
lis = s.select('ul ~ #tertiaryconsumers')
属性条件匹配
#class属性等于 'name'
lis = s.select('div[class="name"]')
#class属性包含了 'na'
lis = s.select('div[class*="na"]')
#class属性以 'me'结尾
lis = s.select('[class$="er"]')
#class属性以 'n'开头
lis = s.select('[class^="n"]')
#包含'class'属性的标签
lis = s.select('[class]')
#查找包含'class'的div 再 查找'id="test"' 的标签
lis = s.select('div[class] [id="test"]')
其他情况
标签属性的值里面有空格
#当class里面有空格时,相当有两个class属性,空格的地方使用 '.' 来表示
lis = s.select('div.class.test') # class="class test"
#解决id里面的空格,直接使用 [] 取属性
lis = s.select('[id="id test"] a ') # id="id test"
爬取的数据为空list的处理
lis = []
# 当list为空时返回 '',其他情况返回list的第一个数据。
r = lis[0] if lis else ''