行吧,第三篇依然是一个简单的爬虫项目,毕竟新手还是要多练练手,熟悉了基本requests和re的使用,以及分析简单的爬虫项目,那么就可以往上进阶了。
今天这个项目主要是训练代码的封装,以及json模块的使用,想学的旁友认真看哈?♂️
- 项目地址:https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0
- 要求:
- 使用requests完成
- 使用json模块来提取数据
- 获取热门电影的名字、评分、电影详情页url
今天来爬一爬豆瓣的热门电影✈️
有过前两次项目经验的旁友,应该都会注意到url了吧?嘿嘿,注意到的同学给你点个赞
确实,简单爬虫项目主要有两个条件,一就是页码数你能在url上发现规律,二就是数据不是js加载的,恰巧这个项目就完全符合。
爬虫的四部曲我就不再重复了,大家应该都了然于心才对,思路很重要。
ok,进入正题,分析分析
可以看到,页面下方有个『加载更多』,那就是说,热门电影不止“一页”展示的数据,还有更多。点击试试。
发现又多了20条数据,并且url发生了变化https://movie.douban.com/explore#!type=movie&tag=热门&sort=recommend&page_limit=20&page_start=20
可以看到,page_start
这个参数+了20,那是不是可以大胆推测,每点一次加载更多就会+20 呢?试试点多几次
虽然验证了,但是又有了新问题,是不是无穷无尽啊这个列表?什么时候才是到头?这个问题我先放着,待会来解决。
既然我们前面说到了json,那么这一次项目肯定不是从url获取content,再利用re获取我们的数据了。先简单说一下什么是json
- JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。适用于进行数据交互的场景,比如网站前台与后台之间的数据交互
- JSON在数据交换中起到了一个载体的作用,承载着相互传递的数据
这么说可能很抽象,说白了他就是一个数据(文件)格式而已,给大伙看看长啥样就行了
people = {"name":"老王", "age":18 ,"hobby": ["唱","跳","rap"]}
这就是json格式。注意json中的字符串
都是双引号引起来的
回到页面上来,那我们怎么去获取这个json数据呢?答案就是,找到返回json数据的接口(别问什么是接口,问就是百度)
打开浏览器,按一下f12,打开“开发者工具”,点击【Network】,然后再刷新一下页面
看到有好多内容,那哪一个才是我们想要的接口呢?
因为我们需要点击【加载更多】才会刷新下一页,所以只要我们点一下,看看【Network】里会不会多一个请求就知道了
点了两三下【加载更多】,看看【Network】
发现最底下有三个前缀相同的请求,到底是不是我们想要的接口呢??点击一个看看。
诶,发现response这里有一长串东西,把他复制到sublime里面看看
20条数据,刚刚好,并且很清晰的看到,我们想要的数据都在里边,那么得出结论,这个就是我们想要找的接口!那么我们只需要把所有的接口都放到urllist里面,再从urllsit遍历出来,用json提取数据就ok啦。
先来看看怎么构建urllsit
看到第一页的接口,跟我们url长得差不多嘛,点下面的那两个接口发现也是每页数据page_start
+20,那问题就简单啦,得到了规律,就可以开始构建urllist了
url = "https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start={}"
urllist = []
n = 0
while True:
urllist.append(url.format(n))
n += 20
if n == 300:
break
print(urllist)
看到这里肯定会疑惑了,为啥n到了300就Break
了?回顾一下前面提出的问题,这个热门电影的列表,到底有多少页(多少条)数据?这边我是直接改page_start
参数,发现到了300的时候就没数据了,到290的时候只有一条数据,并且是280的最后一条数据,也就是说,280这个值就是峰值了。
所以这个urllist就这样构建好了,接下来的步骤就是从json中提取我们想要的数据
json模块是Python自带的模块,用于json与python数据之间的相互转换。
关于更详细的json模块使用就不在此介绍了,有兴趣了解的可以找度娘或者google
由于文章篇幅的问题,我直接放上完整代码,有几个点要说明一下
- 关于urllist,大家可以换别的思路,比如使用捕获异常break死循环这种方法,或者判断返回值等等。。方法很多,我的方法仅供参考
- 代码的封装,这个是一个需要养成的习惯!
- 爬取下来后可以根据自己的需求再进行改进,如数据的排序方式,过滤,其他分类电影的爬取等等
- 关于列表推导式以及zip()的使用,这个如果没看懂的旁友,推荐去百度,并且学会它
最后希望旁友们的爬虫水平越来越高,保持对爬虫的兴趣,让我们共同进步吧!?♀️
import requests
import json
class Douban():
base_url = "https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start={}"
def get_urllist(self):
urllist = []
n = 0
while True:
urllist.append(self.base_url.format(n))
n += 20
if n == 300:
break
return urllist
def get_json(self,url):
data = requests.get(url).text
return data
def get_info(self,data):
dict = json.loads(data)
rate = [i["rate"] for i in dict["subjects"]] #电影评分
title = [i["title"] for i in dict["subjects"]] #电影名
url = [i["url"] for i in dict["subjects"]] #电影详情页url
for rate, title, url in zip(rate, title, url):
print("电影名:" + title + "/" + "评分:" + rate + "/" + "详情url:" + url)
print("-" * 70) # 分割线
if __name__ == '__main__':
spider = Douban()
#获取urllist
urllist = spider.get_urllist()
for i in urllist:
#获取json数据
data = spider.get_json(i)
#从json数据中提取想要的信息
spider.get_info(data)