python爬虫解析库beautifulsoup
美味汤作为一个用于解析网页的第三方库,因为其语法简单,上手容易,开发成本低,因而比较受欢迎,下面便开始对其进行介绍
安装
打开 cmd 输入以下语句便可以安装成功,如果存在安装慢的问题,可以换一下镜像,这里可以参考本人另一篇文章----> 传送门
pip install bs4
简单使用
这样就做了一锅美味的汤了
import requests
from bs4 import BeautifulSoup
url = 'https://www.baidu.com/'
response = requests.get(url)
# response.encoding = response.apparent_encoding
soup = BeautifulSoup(response.text)
进阶
提取文档中的标签
需要注意的是,返回的是第一个满足条件的标签作用效果和soup.find()类似
而find_all()函数是返回文档中所有满足的选项,并以列表的形式返回
我们同时可以以列表的形式将要查找的标签传进去,从而查找多个我们需要查找的标签,比如 a, p
# 提取文档中的标签
soup.p
#<p id="lh"> <a href="http://home.baidu.com">å
# ³äºŽç™¾åº¦</a> <a href="http://ir.baidu.com">About Baidu</a> </p>
soup.find('p')
#<p id="lh"> <a href="http://home.baidu.com">å
# ³äºŽç™¾åº¦</a> <a href="http://ir.baidu.com">About Baidu</a> </p>
# 提取文档中的标签的标签
soup.p.a
# <a href="http://home.baidu.com">å
# ³äºŽç™¾åº¦</a>
soup.find_all('p')
#[<p id="lh"> <a href="http://home.baidu.com">å
# ³äºŽç™¾åº¦</a> <a href="http://ir.baidu.com">About Baidu</a> </p>,
# <p id="cp">©2017 Baidu <a href="http://www.baidu.com/duty/">使用百度å‰å¿
# 读</a> <a class="cp-feedback" href="http://jianyi.baidu.com/">æ„è§å馈</a> 京ICPè¯030173å· <img # src="//www.baidu.com/img/gs.gif"/> </p>]
soup.find_all(['a','p'])
'''
[<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>,
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123</a>,
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图</a>,
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频</a>,
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧</a>,
<a class="lb" href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login">登录</a>,
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon" style="display: block;">更多产品</a>,
<p id="lh"> <a href="http://home.baidu.com">关于百度</a> <a href="http://ir.baidu.com">About Baidu</a> </p>,
<a href="http://home.baidu.com">关于百度</a>,
<a href="http://ir.baidu.com">About Baidu</a>,
<p id="cp">©2017 Baidu <a href="http://www.baidu.com/duty/">使用百度前必读</a> <a class="cp-feedback" href="http://jianyi.baidu.com/">意见反馈</a> 京ICP证030173号 <img src="//www.baidu.com/img/gs.gif"/> </p>,
<a href="http://www.baidu.com/duty/">使用百度前必读</a>,
<a class="cp-feedback" href="http://jianyi.baidu.com/">意见反馈</a>]
'''
按照属性提取标签
我们知道标签里面常常会带有一些属性,比如 class name id 等,用来与其他的标签进行区分,并赋予其一些特殊的属性,我们便可以通过这些指定的属性来查找到这个标签,同样,find()函数是查找第一个,find_all()函数是查找所有并返回为列表
# p 标签
soup.find_all('p', attrs={'id' :'lh' })
# [<p id="lh"> <a href="http://home.baidu.com">å
# ³äºŽç™¾åº¦</a> <a href="http://ir.baidu.com">About Baidu</a> </p>]
# p 标签
soup.find('p', attrs={'id' :'lh' })
#<p id="lh"> <a href="http://home.baidu.com">å
#³äºŽç™¾åº¦</a> <a href="http://ir.baidu.com">About Baidu</a> </p>
提取标签里的文本
# p 标签
soup.p.get_text()
# ' å\x85³äº\x8eç\x99¾åº¦ About Baidu '
获取文档中所有的文本
soup.strings 返回的文本里面会包含很多空白文本,如果不想要这些,可以使用 soup.stripped_strings
for i in soup.strings:
print(i)
for i in soup.stripped_strings:
print(i)
寻找某个节点的父节点
tag.parent 或者 tag.parents
soup.p.parent # 返回第一个p标签的第父节点
'''
<div id="ftConw"> <p id="lh"> <a href="http://home.baidu.com">关于百度</a> <a href="http://ir.baidu.com">About Baidu</a> </p> <p id="cp">©2017 Baidu <a href="http://www.baidu.com/duty/">使用百度前必读</a> <a class="cp-feedback" href="http://jianyi.baidu.com/">意见反馈</a> 京ICP证030173号 <img src="//www.baidu.com/img/gs.gif"/> </p> </div>
'''
# 返回所有p标签的第父节点
for i in soup.title.parents:
print(i)
'''
信息量过大
'''
与正则结合
对正则的介绍与学些可以参考我的另外一篇博客-----> 传送门
我们可以把soup.find()或者其他函数的查找条件用正则替代,以此来简化我们的代码
import os
# 查找标签中有d的标签
for tag in soup.find_all(re.compile("d")):
print(tag.name)
'''
head
body
div
div
div
div
div
div
div
div
div
'''
True 可以匹配任意值
for i in soup.find_all(True):
print(i.name)
'''
html
head
meta
meta
meta
link
等等等
'''
css 选择器(select 函数)
通过标签
soup.select('a')
'''
[<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>,
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123</a>,
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图</a>,
省略部分
<a class="cp-feedback" href="http://jianyi.baidu.com/">意见反馈</a>]
'''
通过id 和 class
# 通过 class 查找
soup.select('.lb')
'''
[<a class="lb" href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login">登录</a>]
'''
# 通过id 查找
for i in soup.select('#head'):
print(i.get_text())
'''
新闻 hao123 地图 视频 贴吧 登录 document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');
更多产品
'''
通过属性
soup.select('a[class="mnav"]')
'''
[<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>,
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123</a>,
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图</a>,
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频</a>,
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧</a>]
'''
select_one 函数
和之前的find 函数类似,返回第一个匹配的结果
soup.select_one('a[class="mnav"]')
# <a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>
这里列出一些比较常见的用法,还有很多函数没有提及,想要了解更多的同学可以参考官方文档