1、问题
想要爬取豆瓣手机版的热播剧页面中的英美剧页面的内容,在将豆瓣电视剧的json字符串保存到本地的时候报错:KeyError: ‘subject_collection_items’。
2、过程
通过查找,在以idems开头的url请求中找到了页面所包含的数据。
找到url里是用的start来表示当前页面显示的是哪些电视剧。
可以看到数据在这个subject_collection_items字典中。
3、代码
import requests
import json
class DoubanSpider():
def __init__(self):
self.url_temp = "https://m.douban.com/rexxar/api/v2/subject_collection/tv_american/items?start={}&count=18&loc_id=108288"
self.headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
}
def parse_url(self, url):
"""发送请求,获取响应"""
print(url)
r = requests.get(url, headers=self.headers)
return r.content.decode()
def get_content(self, json_str):
"""提取数据"""
dict_ret = json.loads(json_str)
# 此键对应的值是一个列表
content_list = dict_ret["subject_collection_items"]
# 获取电视剧的总数
total = dict_ret["total"]
return content_list, total
def save_content(self, content_list):
"""保存数据"""
# a是追加
with open("douban.txt", "a") as f:
for content in content_list:
f.write(json.dumps(content, ensure_ascii=False))
# 写入换行符,进行换行
f.write("\n")
print("保存成功")
def run(self):
"""实现主要逻辑"""
num = 0
# 先假设一个total, 以后都用这种方式判断数据是否到最后了
total = 100
while num < total+18:
# 1、开始页url
url = self.url_temp.format(num)
# 2、发送请求,获取响应
json_str = self.parse_url(url)
# 3、提取数据
content_list, total = self.get_content(json_str)
# 4、保存
self.save_content(content_list)
# 当该页的数据小于18时,说明这是最后一页了,要结束循环了
# if len(content_list) < 18:
# break
# 5、构造下一页的url地址,进入循环
num += 18
if __name__ == "__main__":
douban_spider = DoubanSpider()
douban_spider.run()
点击运行,报错如下。
4、解决
没有找到subject_collection_items, 尝试在浏览器中去访问一下那个url,发现是无效请求,也print了一下字典,发现确实没有,拿不到数据。
经过一番摸索,发现headers里还有另一个东西Referer。
在代码中加上这一句。
点击运行,成功爬取数据。
完美解决,欢迎各位大佬指出错误。