这篇博客主要是从具体的分析Ajax请求抓取今日头条街拍美图入手,通过项目来学习相关的爬虫技术,以做代学。
分析Ajax请求抓取今日头条街拍美图
前提概念补充
有时候我们在用request
抓取页面的时候,得到的结果和浏览器中看到的可能不一样,在浏览器中看到的是正常显示的页面数据,但是在request
得到的结果并没有。这是因为获取得到的都是原始的HTML
文档,但是浏览器页面是经过 JavaScript
处理数据后生成的结果。这些数据可能是通过Ajax
加载得到的。
对于Ajax
加载数据的情况来说,数据加载是一种异步加载的方式,原始的页面最初不会包含某些数据,原始页面加载完成之后,会再向服务器请求某个接口获取数据。然后数据才会被处理从而呈现在网页上。这其实就是发送了一个Ajax
请求。现在网页发展就是这样:网页原始的HTML
文档不包含任何数据,数据都是通过Ajax
统一加载之后呈现出来的,这样就可以在Web
开发商可以做前后端分离,而且降低服务器直接渲染页面带来的压力。
如果遇到这样的页面是无法获取有效数据的,这时就需要分析网页后台向接口发送的Ajax
请求,如果可以用requests
来模拟Ajax
请求,那么就可以成功抓取了。
- Ajax
在说这个项目之前,一般的爬虫小白都会对这个标题中的
Ajax
产生疑问需要先解释一下Ajax
。Ajax
就是Asynchronous JavaScript and XML
(异步的JavaScript
与XML
技术)说白了就是在不关闭不跳转不刷新的情况下,在网页后台提交数据,部分更新页面的内容。在这个过程中,页面实际上是在后台与服务器进行了数据交互,获取到数据之后,再利用JavaScript
改变网页,这样网页内二就会更新了。举例说明:我们查看微博的时候,都会看到查看了一定版面的微博之后,会出现一个加载的动画,过一会之后会出现新的微博。这个加载的过程就是
Ajax
加载。
Ajax
请求步骤:
- 发送请求
- 解析内容
- 渲染网页
- JSON
还有一个需要介绍的概念(别怪我啰嗦,因为我也是小白,对web知识了解的也不多,边做边学)是
JSON
,这个学术上的名称是JavaScript Object Notation
,本质上说他是一种传递对象的语法,对象可以是name/value键值对,数组和其他对象。主要组成是:{}、[]、:、,
- pycharm 相同目录下引用其他文件
pycharm不会将当前文件目录自动加入自己的source_path.右键make_directory as->source path 将当前工作的文件夹加入 source_path就可以了。
项目结构
好了,之前我们说到了真实数据是Ajax
请求得到的,如果想抓取这些数据,需要知道这些请求时怎么发送的,发送到哪里,发了哪些参数。请看Ajax
分析:
查看请求
在微博界面上按
F12
键,便可以弹出开发者模式。在Element
选项卡中可以查看网页源代码,点击Network
选项卡,之后再重新刷新页面,可以发现有很多条目,这个就是页面加载过程中浏览器与服务器之间发送请求和接受响应的所有记录。在这些记录里面查找
Ajax
请求的方法:我们可以在getIndex
开头的信息里面找到一个,其Type
为xhr
的请求类型,这就是Ajax
。我们看到的微博页面的真实数据并不是原始页面返回的,而是后来执行
JavaScript
后再次向后台发送了Ajax
请求,浏览器拿到数据之后进一步渲染出来的。过滤请求
浏览器里按F12出现开发者工具筛选功能筛选出所有的
Ajax
请求,在请求上方有一层筛选栏,直接点击XHR
,此时下方显示的所有请求就是Ajax
请求了。向下滑动网页,可以看到有新的Ajax
请求出现。
这个项目说实话是一个比较基本的爬虫练手项目,目的是爬取今日头条上的美女图片。主要的流程框架是:
抓取索引页内容
利用request请求目标站点,得到索引网页HTML代码,返回结果。
抓取详情页内容
解析返回结果,得到详情页的链接,并进一步抓取详情页的信息
开启循环及多线程
对多页内容遍历,开启多线程提高抓取速度
下载图片与保存数据库
将图片下载到本地,并把页面信息及图片URL保存至MongoDB
好了,介绍完大体架构了,然后就要开始实操了。我用的是pycharm来写python代码的。界面比较友好,这里推荐一下。然后再介绍一下pycharm的快捷键,方便大家快速便捷地写出优雅的代码。

代码分析
代码文件总共是两个,一个是spider.py,一个是config.py文件。
- spider.py
1 | # 在URL中没有相应的搜索字段,可以判断网页内容是`Ajax`加载,然后用`JavaScript`渲染出来的,接下来切 |
- config.py
1 | MONGO_URL = 'localhost' |