2.9 异步加载

一、介绍

有时候我们在用requests抓取页面的时候,得到的结果可能和在浏览器中看到的不一样。这是因为requests获取的都是原始的HTML文档,而浏览器中的页面则是经过JavaScript处理数据后生成的结果,这些数据的来源有多种,可能是通过Ajax加载的,可能是包含在HTML文档中的,也可能是经过JavaScript和特定算法计算后生成的。

对于第一种情况,数据加载是一种异步加载方式,原始的页面最初不会包含某些数据,原始页面加载完后,会再向服务器请求某个接口获取数据,然后数据才被处理从而呈现到网页上,这其实就是发送了一个Ajax请求。

照Web发展的趋势来看,这种形式的页面越来越多。网页的原始HTML文档不会包含任何数据,数据都是通过Ajax统一加载后再呈现出来的,这样在Web开发上可以做到前后端分离,而且降低服务器直接渲染页面带来的压力。

所以如果遇到这样的页面,直接利用requests等库来抓取原始页面,是无法获取到有效数据的,这时需要分析网页后台向接口发送的Ajax请求,如果可以用requests来模拟Ajax请求,那么就可以成功抓取了。

二、认识Ajax

1、打开堆糖网页,搜索‘‘新垣结衣’’后,展现出来的网页的内容只有24张图片,但是下滑右边的滑块到底后,就会刷新出新的图片,不断地下滑就会有新的内容不断刷出来,这是因为每次到底的时候,客户端就向服务器发送了新的请求,获得了新的数据。

使用检查元素可以帮助我们看到这其中发生的变化,在Network中找到XHR类型,这是Ajax的特殊请求类型,

右侧可以看到很多信息,如Request Headers、URL和Response Headers,其中Request Headers中有一个信息为X-Requested-With:XMLHttpRequest,这就标记了此请求是Ajax请求。

点击preview,可以看到其中的信息是前面加载出来的24张图片的信息,并且是是JSON格式的。

在点击response,以及最初的response,可以发现后来的response中的内容并未在前面出现,因此是后来加载的

这里我和原文博主的内容不太一样

接下来,再利用Chrome开发者工具的筛选功能筛选出所有的Ajax请求。在请求的上方有一层筛选栏,直接点击XHR,此时在下方显示的所有请求便都是Ajax请求了

接下来,不断滑动页面,可以看到页面底部有一条条新的微博被刷出,而开发者工具下方也一个个地出现Ajax请求,这样我们就可以捕获到所有的Ajax请求了。

随意点开一个条目,都可以清楚地看到其Request URL、Request Headers、Response Headers、Response Body等内容,此时想要模拟请求和提取就非常简单了。

三、结果提取

1、分析请求

可以发现,这是一个GET类型的请求,请求链接为https://www.duitang.com/napi/blog/list/by_search/?kw=新垣结衣&type=feed&include_fields=top_comments%2Cis_root%2Csource_link%2Citem%2Cbuyable%2Croot_id%2Cstatus%2Clike_count%2Csender%2Calbum&_type=&start=24&_=1525497770697。请求的参数有4个:include_fields、_type、start和_。

随后再看看其他请求,可以发现,它们的前两个参数始终如一。其中start为24,刚好是每次加载图片的个数,而_参数每加载一次,数值就增加一,但是这个初始数值如何得来,我还不清楚。

2、分析响应

图片

这个内容是JSON格式的,浏览器开发者工具自动做了解析以方便我们查看。可以看到,最关键的信息就是data中的object_list,它包含了每个加载图片的信息,其中path中对应的就是每个图片的链接

3、具体代码

Last updated

Was this helpful?