任务1:完成百度贴吧和requests部分的代码。掌握面向对象方式处理网络爬虫的设计过程。
百度贴吧和requests部分的代码:
import requests
class BaiduBar:
"""百度贴吧爬虫"""
def __init__(self, bar_name='李毅'): # 初始化为'李毅'
# 1.初始化请求地址
self.url = 'https://tieba.baidu.com/f?kw=' + bar_name + '&ie=utf-8&pn={}'
self.name = bar_name
@staticmethod
def get_response(request_url):
"""发送请求并获取响应"""
response_content = requests.get(url=request_url).content.decode('utf-8')
return response_content
def write_to_file(self, content, page_index):
# 定义文件名称
file_name = f'{self.name}吧 - 第{page_index}页.html'
with open(f'./百度贴吧/{file_name}', 'w', encoding='utf-8') as f:
f.write(content)
def run(self, page_nums=5): # 爬取5页的内容
"""爬虫启动方法"""
# 1.确认请求地址
for index in range(page_nums): # index => 0 1 2 3 4
# 1.1 拼接请求地址
url = self.url.format(index * 50) # 'https://tieba.baidu.com/f?kw=%E6%9D%8E%E6%AF%85&ie=utf-8&pn=4'
# 1.2 发送请求并获取响应
html_content = self.get_response(url)
# 1.3 保存响应内容
self.write_to_file(html_content, index + 1)
if __name__ == '__main__':
BaiduBar(bar_name='美女').run()
面向对象方式处理网络爬虫的设计过程:
1.请求网页
通过 HTTP 库向目标站点发起请求,即发送一个 Request,请求可以包含额外的 headers 等信息,等待服务器响应!
2.获得相应内容
如果服务器能正常响应,会得到一个 Response,Response 的内容便是所要获取的页面内容,类型可能有 HTML,Json 字符串,二进制数据(如图片视频)等类型。
3.解析内容
得到的内容可能是 HTML,可以用正则表达式、网页解析库进行解析。可能是 Json,可以直接转为 Json 对象解析,可能是二进制数据,可以做保存或者进一步的处理。
4.存储解析的数据
保存形式多样,可以存为文本,也可以保存至数据库,或者保存特定格式的文件。
任务2:利用requests下载一张网络图片并保存到本地(作业1),提交到钉钉群第一次作业文件夹中,命名以学号+姓名的方式。比如9527张三.py
import requests
def download_img(url):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'}
r = requests.get(url, headers=headers, stream=True)
if r.status_code == 200:
img_name = url.split('/').pop() # 截取图片文件名:28
with open('图片'+img_name, 'wb') as f: # 保存图片文件名为"图片28.jpg"至本地文件夹
f.write(r.content)
return True
if __name__ == '__main__':
# 下载图片
img_url = "http://www.py3study.com/Public/images/article/thumb/random/28.jpg"
re = download_img(img_url)
if re:
print("下载成功,并已经保存到本地文件夹!")
else:
print("下载失败!")
任务3:掌握json的写法,理解json是什么。尝试写一个json来描述一个王者荣耀玩家的信息。提交最后的xxx.json到第二次作业文件夹中,命名方式以学号+姓名的方式。如9527.json
{
"player_name": "王梓权",
"play_days": 100,
"hero_Record": [
{
"ename": 133,
"cname": "狄仁杰",
"title": "断案大师",
"new_type": 0,
"hero_type": 5,
"skin_name": "断案大师|锦衣卫|魔术师|超时空战士|阴阳师",
"moss_id": 3781
},
{
"ename": 134,
"cname": "达摩",
"title": "拳僧",
"new_type": 0,
"hero_type": 1,
"hero_type2": 3,
"skin_name": "拳僧|大发明家|拳王",
"moss_id": 3798
}
],
"game_section": "永恒钻石",
"recharge": 0
}
任务4:完成json解析的案例代码。掌握json解析数据的方式。能够做到给任意json文件都能根据需求提取到json中想要的数据即可。
{
"class_id": 10001,
"class_teacher": "刘德华",
"class_students": [
{
"student_id": 9527,
"student_name": "张三",
"student_sex": "男",
"student_bed_num": "30号楼110-1床",
"student_scores": [
{
"subject": "C语言",
"subject_score": 90.2
},
{
"subject": "python",
"subject_score": 80.2
}
]
},
{
"student_id": 9528,
"student_name": "李四",
"student_sex": "男",
"student_bed_num": "30号楼110-2床",
"student_scores": [
{
"subject": "C语言",
"subject_score": 60.2
},
{
"subject": "python",
"subject_score": 50.2
}
]
},
{
"student_id": 9529,
"student_name": "王五",
"student_sex": "男",
"student_bed_num": "30号楼110-3床",
"student_scores": [
{
"subject": "C语言",
"subject_score": 100
},
{
"subject": "python",
"subject_score": 90
}
]
}
],
"class_info":{
"class_major": "信息工程",
"major_address": "xxx4楼",
"major_manager": "郭富城"
}
}
import json
def load_json(file_path):
"""加载外部json文件"""
with open(file_path, 'r', encoding='utf-8') as f:
# 读取json文件
json_str = f.read()
# 关闭流对象
f.close()
return json_str
if __name__ == '__main__':
# 1.获取json文件并输入json内容
json_str = load_json('./class.json')
# 2.将读取到的json字符串装换成python对象
json_py_object = json.loads(json_str)
# 3.提取数据
# 3.1 提取所有学生的姓名
for stu in json_py_object['class_students']:
print(f"学生{stu['student_name']}住在{stu['student_bed_num']}")
# 3.2 提取学生的所有成绩
for stu in json_py_object['class_students']:
for stu_subject in stu['student_scores']:
print(f"学生{stu['student_name']}的科目:{stu_subject['subject']}的成绩是:{stu_subject['subject_score']}")
Json数据主要分为对象、数组、键值对。
{ }表示一个对象,[ ]表示数组,“name”: 5 表示键值对(数据),前面name 表示标识,后面5是值,值可以是int、char、string等类型。“:”冒号用于分隔数据的“名”和“值”,对象和数组可以互相包含,但是对象不可以直接包含对象也不可以直接包含数组,数组不能直接存放数据(键值对)。
json数据解析也支持链式编程。
json数据的解析其实也就是一层一层解析,通过对应的标号名来获取对应的值来获取数据,归根结底就是要去一层一层找标号名(索引名),然后通过名就可以得到实际需要的数据。
json数据的组成方式是千变万化的,但是归根结底都是对象、数组、名值对这三个组成,只要掌握了以上的方法,灵活运用,基本就可以实现任意json数据的自我解析。