爬豆瓣
什么是 AJAX ?
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
AJAX = Asynchronous JavaScript and XML(AJAX = 异步 JavaScript 和 XML。)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。
动态加载的数据
通过另一个单独的请求请求到的数据
如果我们要对一个陌生的网站进行指定数据的爬取?
首先要明确爬取的数据在该网站是否为动态加载的
如何判断?
- 浏览器中按F12打开开发者工具,然后点击Network下的All
- 刷新网页,可以看到很多请求,直接找到第一个点击
- 然后在Response里按ctrl+F全局搜索
- 在全局搜索框中输入网页中的任意标题或者比较容易辨认的文字或者数字
- 如果可以查到,证明不是动态加载的,反之就是动态加载
是:通过浏览器抓包工具实现全局搜索,定位动态加载数据对应的数据包,从数据包中提取请求的url和请求参数。
不是:就可以直接将浏览器地址栏中的网址作为我们requests请求的url。
首先我们通过浏览器随机进入豆瓣主页的一个分类,下面我这个网址是代表着(热门电视剧)分类:
https://movie.douban.com/tv/#!type=tv&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0
我们往下翻,发现没有下一页,而是四个字:加载更多,我们点击它后,又加载出了一些电视剧,那我们观察一下此时网页的url变成了:
https://movie.douban.com/tv/#!type=tv&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=20
变化就在于最后的start=0变成了start=20,而且整张页面并没有重新加载,页面最下方就加载出了数据,那么我们可以判断这些新加载出来的数据肯定是AJAX动态加载的了。
上面说了动态加载的数据是另一个单独的请求请求到的数据,现在我们就把它找出来。
- 在浏览器中按F12打开开发者工具
- 点击Network下的XHR(XHR就是 XMLHttpRequest 对象,也就是ajax功能实现所依赖的对象),这样我们就能看到AJAX发出的请求
- 点击第二行的clear(一个小圆圈中间有个反斜杠)方便我们观察在点击加载更多后发出了什么请求
果然我们发现了一个请求,点击它,可以看到里面有Headers和Response
Response下返回的是json数据,我们打开json在线解析工具https://www.json.cn/,然后解析,会发现这些数据就是我们点击加载更多后新加载出来的数据
而我们观察一下page_limit:和page_start:
page_limit=20&page_start=0(页面初始时),此时页面共有20部电视剧
page_limit=20&page_start=20(第一次点击加载更多时),此时页面共有40部电视剧
page_limit=20&page_start=40(第二次点击加载更多时),此时页面共有60部电视剧
由此得出结论,从page_start开始,加载page_limit个电视剧
而Headers下有
以及Request URL,Request URL则包含着这些参数
那我们就直接请求去掉参数的Request URL,然后请求时再把参数加上,这样参数可以动态化。
以下为完整代码:
import requests url = 'https://movie.douban.com/j/search_subjects' headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36' } page_start = input('您想从第几部电影开始获取:') page_limit = input('您想一次获取多少部电影:') #url里携带的参数 dic = { 'type': 'tv', 'tag': '热门', 'sort': 'recommend', 'page_limit': page_limit, 'page_start': page_start, } response = requests.get(url=url,params=dic,headers=headers) page_text = response.json()#json返回的是序列化好的实例对象 print(page_text)#page_text是一个字典,数据在字典键值对中的值里面 for dic in page_text['subjects']: _title = dic['title'] _rate = dic['rate'] print(_title+_rate)
https://movie.douban.com/j/search_subjects?type=tv&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=20