大家好呀~这节课我们继续学习爬虫的基础知识。上节课我们学习了resquest、response 和 Xpath 的使用,做了一个爬取百度贴吧前50页的帖子标题的小练习。这节课我们将会学习新的三块内容:
- BeautifulSoup 网页解析库的适用
- JSON 数据的处理
- 动态网页数据的获取
一、BeautifulSoup 库的基本使用
1、简介
BeautifulSoup
库是一个灵活又方便的网页解析库,处理高效,支持多种解析器。大家可以参考它的 中文参考文档。
2、基本使用
from bs4 import BeautifulSoup
html = '''
<body>
<header id="header">
<h3 id="name">小强也可爱</h3>
<title>标题</title>
<div class="sns">
<a href="http://www.kaikeba.com/feed/" target="_blank" rel="nofollow" title="RSS"><i class="fa fa-rss" aria-hidden="true"></i></a>
<a href="http://kaikeba.com/kaikeba" target="_blank" rel="nofollow" title="Weibo"><i class="fa fa-weibo" aria-hidden="true"></i></a>
<a href="https://www.kaikeba.com/in/kaikeba" target="_blank" rel="nofollow" title="Linkedin"><i class="fa fa-linkedin" aria-hidden="true"></i></a>
<a href="mailto:kaikeba@gmail.com" target="_blank" rel="nofollow" title="envelope"><i class="fa fa-envelope" aria-hidden="true"></i></a>
</div>
<div class="nav">
<ul>
<li class="current-menu-item"><a href="http://www.kaikeba.com/">hello</a></li>
<li><a href="http://www.kaikeba.com/about-me/">word</a></li>
<li><a href="http://www.kaikeba.com/post-search/">nihao</a></li>
<li><a href="http://www.kaikeba.com/wp-login.php">kkb</a></li>
</ul>
</div>
</header>
</body>
'''
soup = BeautifulSoup(html,'lxml')
# 格式化输出 soup 对象的内容
print(soup.prettify())
# 根据标签名获取整个标签(但是拿出的是第一个)
print(soup.li)
# 获取标签的名字
print(soup.title.name)
# 获取标签中的文本
print(soup.title.string)
# 获取标签title的父标标签
print(soup.title.parent.name)
# 获取li标签的子标签
print(soup.li.contents)
# 获取便签的属性值的两种方式
print(soup.li["class"])
print(soup.li.attrs['class'])
# 使用select,css选择器
print(soup.select('li'))
# 类名前加.,id名前加#
print(soup.select('.current-menu-item'))
# 获取内容
print(soup.select('.current-menu-item')[0].get_text())
# 获取属性值
print(soup.select('.current-menu-item')[0].attrs['class'])
# 获取li标签下面的子标签
print(soup.select('li > a')[1].get_text())
# 使用find和findall进行查找
print(soup.find('li',attrs={'class':'current-menu-item'}))
print(soup.find_all('li',attrs={"class":"current-menu-item"})[0])
不同解析器对比:
image.png3、BeautifulSoup
练习
soup = BeautifulSoup(result_str,'lxml')
# 获取文本
texts = [i.get_text() for i in soup.find_all('a',attrs = {'class':"j_th_tit"})]
# 获取连接
lins = ['https://tieba.baidu.com{}'.format(i.attrs['href']) for i in soup.find_all('a',attrs = {'class':"j_th_tit"})]
注意: 上面把 for 循环写到一个方括号中的式子叫列表生成式,它的作用是为了简化代码,但是不建议初学者使用,因为其逻辑性较强。我们以第一个式子为例来拆解一下,前面的 i.get_text()
是我们要从遍历出来的每个元素中获取的内容,后面是我们用来遍历的 for 循环。
二、Json
JSON 是一种轻量级的数据交换格式,它使得人们很容易进行阅读和编写。同时也方便了机器进行解析和生成,适用于进行数据交互的场景,比如网站前台与后台之间的数据交互。
image.png1、JSON 语法规则
- 数据在名称/值对中
- 数据由逗号分隔
- 花括号保存字典对象
- 方括号保存数组
2、JSON 值
JSON 值可以是:
- 数字(整数或浮点数)
- 字符串(在双引号中)
- 逻辑值(true 或 false)
- 数组(在方括号中)
- 对象(在花括号中)
- null
3、JSON 模块
通过 Python 的 json 模块,可以将字符串形式的 json 数据转化为字典,也可以将 Python 中的字典数据转化为字符串形式的 json 数据。
(1) dumps
dumps
可以将 obj
类型的数据转化为 JSON 格式的字符串。
dict1 = {
'Code': 200,
'Count': 657,
'Posts': [
{
'Id': 0,
'PostId': "1123178321664806912",
'RecruitPostId': 49691
},
{
'Id': 0,
'PostId': "1123178321664806912",
'RecruitPostId': 49691
}
]
}
json_dict = json.dumps(dict1)
print(json_dict)
print(type(json_dict))
(2)loads
loads
可以将包含 str
类型的 JSON 文档反序列化为一个 python 对象。
dic = json.loads('{"name":"Tom", "age":23}')
print(dic)
print(type(dic))
三、动态数据获取
获取鹅厂招聘信息:
import requests
import json
import time
now_time = int(time.time())
jiang_13 = now_time*1000
# 注意:这里的 timestamp 时间戳,是指距离1970年多少秒或者毫秒。我们之所以要传入这个参数,是为了更好地伪装成真实用户
base_url = 'https://careers.tencent.com/tencentcareer/api/post/Query?timestamp={}&keyword=Python&pageIndex=1&pageSize=10&language=zh-cn&area=cn'
headers = {
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
}
response = requests.get(url=base_url.format(jiang_13),headers=headers)
print(response.content.decode('utf-8'))
# 将数据转化成Python对象
content_dict = json.loads(response.content.decode('utf-8'))
posts_list = content_dict['Data']['Posts']
print(posts_list)
for value_dict in posts_list:
# 招聘的海报的名字
RecruitPostName = value_dict['RecruitPostName']
# 职 责
Responsibility = value_dict['Responsibility']
# 最后更新时间
LastUpdateTime = value_dict['LastUpdateTime']
print(RecruitPostName,Responsibility,LastUpdateTime)
由于爬虫的知识点比较细碎,课程也只是作为简单入门了解,所以仅凭这两课的内容可能很难掌握,因此,大家可以课下找一些不错的爬虫书来学习,或者一边看官方文档,一遍自己爬取一些感兴趣的内容。
在实践中学习永远是效率最高、效果最好的方式。比如我之前学完这一课,就找了一个自己经常访问的PPT网站爬取了几千张好看的PPT素材图片,以供自己工作中使用。在自己写代码、分析网页内容结构的过程中,基本课上所有的知识点都在脑子里过了好几遍,甚至还去查了一些课上没有讲到的小技巧。所以,实践出真知,快动手“爬”起来吧~
网友评论