1,数据提取
从响应中获取我们想要的数据的过程
多种不同类型的响应内容;我们只需要响应内容中的一部分数据
2,数据提取之json
1,一种轻量级的数据交换格式
2,方便了机器进行解析和生成,适用于进行数据交互的场景,比如web的前台和后台之间的数据交互 {"subject" : value }
3,json对象格式化网址:JSON在线解析及格式化验证 - JSON.cn
3,json模块中方法的学习
dump直接到文件,而dumps到一个字符串,这里的s可以理解为string。
import json
#一,【dumps方法】
data = [{'a':'A','b':(2,4),'c':3.0}]
print('DATA:',repr(data))
print("DATA_STR:",str(data))
data_string = json.dumps(data) #把pyton数据类型转换为json串 “”
print("JSON:",data_string)
print("JSON:",type(data_string)) #json是字符串 ""
#二,【dump方法】
data = [{'a':'A','b':(2,4),'c':3.0,'name':'互动'}]
with open('output_1.json','w',encoding='utf-8') as fp:
# fp.write(str(data)) x
json.dump(data,fp,ensure_ascii=False)
json对象decode解码为Python可以识别的对象:
基于string--用json.loads方法
文件 -- 用json.load方法
#一,【loads方法】
data = [{'a':'A','b':(2,4),'c':3.0,'name':'互动'}]
data_string = json.dumps(data) # [{"a": "A", "b": [2, 4], "c": 3.0, "name": "互动"}]
decoded_json = json.loads(data_string) #加载成列表 # [{'a': 'A', 'b': [2, 4], 'c': 3.0, 'name': '互动'}]
print(decoded_json,type(decoded_json))
print(decoded_json[0]['name'])
#二,【load方法】 从文件中,加载json串
with open('output_1.json',encoding='utf-8') as fp:
loaded_json = json.load(fp) #[{'a': 'A', 'b': [2, 4], 'c': 3.0, 'name': '互动'}]
print(loaded_json,type(loaded_json))
4,json.dumps常用参数
参数,可以让我们更好地控制输出
import json
#1,sort_keys 排序参数
data = [{'a':'A','e':(2,4),'c':3.0}]
print("DATA:",repr(data))
print("JSON:",json.dumps(data))
print("SORT:",json.dumps(data,sort_keys=True))
# 2,indent 缩进参数
print("INDEX:\n",json.dumps(data,sort_keys=True,indent=2))
# 3,separators 分割分离符号 去除空格,分隔符
print("dumps(data,separators)\n:",json.dumps(data,sort_keys=True,indent=2,separators=(',',':')),len(json.dumps(data,sort_keys=True,indent=2,separators=(',',':'))))
# 4,skipkeys 跳转参数
data = [{'a':'A','e':(2,4),'c':3.0,('d',):'D tuple',1:'integer','f':'info'}]
print('First attempt')
try:
print(json.dumps(data))
except (TypeError,ValueError) as err:
print("ERROR:",err)
print()
print('Second attempt')
print(json.dumps(data,skipkeys=True))
5,爬取豆瓣网的影视json数据
爬取豆瓣电视剧的英剧和美剧的数据,并分类,地址:https://m.douban.com/tv/
import json
from requests_html import HTMLSession
class Douban(object):
def __init__(self, tv_name):
self.start_url = 'https://movie.douban.com/j/search_subjects?type=tv&tag={}&sort=recommend&page_limit=20&page_start={}'
self.referer = 'https://m.douban.com/movie/subject/{}/'
self.tv_msg = 'https://m.douban.com/rexxar/api/v2/tv/{}?ck=&for_mobile=1'
self.tv_name = tv_name
def run(self):
"""
拼接url,获取翻页信息
:return:
"""
for i in range(5):
# 拼接url,获取翻页信息
url = self.start_url.format(self.tv_name, i)
# 获取url响应的json数据,并转换成字典
tv_list_json = json.loads(session.get(url).content.decode())
self.parse_json_data(tv_list_json)
def parse_json_data(self, json_data):
"""
json数据解析
:param json_data: json_data
:return:
"""
# 遍历字典,获取需要的数据
for tv in json_data['subjects']:
# 电视剧标题
tv_title = tv['title']
# 电视剧的url
tv_url = tv['url']
# 电视剧的图片地址
tv_img = tv['cover']
# 电视剧的id
tv_id = tv['id']
self.parse_tv(tv_id, tv_title, tv_url, tv_img)
def parse_tv(self, tv_id, tv_title, tv_url, tv_img):
"""
:param tv_id:
:return:
"""
# 拼接电视剧详细信息的url
url = self.tv_msg.format(tv_id)
# 反反爬,拼接referer
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Appl\
eWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
'referer': self.referer.format(tv_id)}
# 获取json数据,转化为字典
tv_json_data = json.loads(session.get(url, headers=headers).content.decode('utf-8'))
# 获取电视剧简介
intro = tv_json_data['intro']
self.actor_msg(tv_json_data, tv_title, tv_url, tv_img, intro)
def actor_msg(self, tv_json_data, tv_title, tv_url, tv_img, intro):
name = []
# 演员在字典中,循环取出演员名
for actor in tv_json_data['actors']:
name.append(actor)
self.save(name, tv_title, tv_url, tv_img, intro)
def save(self, name, tv_title, tv_url, tv_img, intro):
with open('tv.txt', 'a+', encoding='utf-8')as f:
# 构造上下文
content = {
'类别': self.tv_name,
'标题': tv_title,
'播放链接': tv_url,
'封面链接': tv_img,
'内容简介': intro,
'演员': name
}
f.write(str(content) + '\r\n')
print('{}{}保存完成'.format(self.tv_name, tv_title))
if __name__ == '__main__':
print("1: '美剧', 2: '英剧'")
session = HTMLSession()
while True:
num = input('请输入对应的编号, 按回车结束')
if num == '1' or num == '2':
data = {1: '美剧', 2: '英剧'}
douban = Douban(data[int(num)])
douban.run()
continue
if num == '0':
break
else:
print('输入有误')