ajax抓取网页内容(用requests抓取页面的结果是什么?如何去分析和Ajax请求)
优采云 发布时间: 2022-04-04 07:19ajax抓取网页内容(用requests抓取页面的结果是什么?如何去分析和Ajax请求)
当我们使用requests对页面进行爬取时,得到的结果可能与我们在浏览器中看到的不一样:在浏览器中正常显示的页面数据,但是使用requests却没有得到任何结果。这是因为请求都是原创的 HTML 文档,而浏览器中的页面是 JavaScript 数据处理的结果。这些数据有多种来源,可能通过 Ajax 加载,可能收录在 HTML 文档中,也可能由 JavaScript 和特定算法生成。
对于第一种情况,数据加载是一种异步加载方式。原创页面将不收录某些数据。只有加载完成后,才会向服务器请求一个接口获取数据,然后将数据处理并呈现给网页。上面,这个过程实际上是向服务器接口发送一个 Ajax 请求。
根据Web的发展趋势,这种形式的页面将会越来越多。网页的原创HTML文档不收录任何数据,通过Ajax统一加载后呈现数据,这样在Web开发中可以分离前后端,服务器直接渲染带来的压力页面缩小。
所以如果遇到这样的页面,直接使用requests之类的库爬取原创页面是无法获取有效数据的。这时候我们就需要分析网页后端向接口发送的Ajax请求了。如果我们可以使用requests来模拟ajax请求,就可以成功抓取。
因此,在本课中,我们将学习什么是 Ajax,以及如何分析和抓取 Ajax 请求。
什么是阿贾克斯
Ajax,全称是Asynchronous JavaScript and XML,即异步JavaScript和XML。它不是一种编程语言,而是一种使用 JavaScript 与服务器交换数据并更新网页的部分内容而不刷新页面且页面链接不改变的技术。
传统网页,如果要更新其内容,就必须刷新整个页面。使用 Ajax,可以在不完全刷新的情况下更新页面内容。在这个过程中,页面实际上是在后台与服务器交互的。获取到数据后,使用 JavaScript 改变网页,从而更新网页的内容。
你可以去 W3School 体验几个 demo 来感受一下:
示例介绍
在浏览网页的时候,我们会发现很多网页已经向下滚动,可以查看更多选项。以我的微博主页为例:. 当我们切换到微博页面,发现往下滑了几条微博后,后面的内容并不会直接显示出来,而是会出现一个加载*敏*感*词*。加载完成后,下方会不断出现新的微博内容。这个过程其实就是Ajax加载的过程,如图:
我们注意到页面并没有完全刷新,也就是说页面的链接没有变化,但是页面中有新的内容,也就是后来刷新的新微博。这就是通过 Ajax 获取和呈现新数据的方式。
基本的
在对Ajax有了初步的了解之后,我们再来详细了解一下它的基本原理。向网页更新发送 Ajax 请求的过程可以简单分为以下 3 个步骤:
下面我们将详细描述这些过程中的每一个。
发送请求
我们知道JavaScript可以实现页面的各种交互功能,Ajax也不例外。它由 JavaScript 实现,实际执行如下代码:
这是 JavaScript 对 Ajax 的底层实现。这个过程其实就是新建一个XMLHttpRequest对象,然后调用onreadystatechange属性设置*敏*感*词*,最后调用open()和send()方法向一个链接(即服务器)发送请求。
我们使用 Python 发送请求后,可以得到响应结果,但是这里的请求是通过 JavaScript 发送的。由于设置了*敏*感*词*器,当服务器返回响应时,会触发onreadystatechange对应的方法,我们可以在这个方法中解析响应内容。
解析内容
得到响应后会触发onreadystatechange属性对应的方法,可以通过xmlhttp的responseText属性获取响应内容。这类似于 Python 中使用 requests 向服务器发出请求,然后得到响应的过程。
返回的内容可能是 HTML 或 JSON,然后我们只需要在方法中使用 JavaScript 进一步处理即可。例如,如果返回的内容是 JSON,我们可以对其进行解析和转换。
呈现网页
JavaScript 具有更改网页内容的能力。解析响应内容后,可以调用 JavaScript 对网页进行解析处理。例如,通过document.getElementById().innerHTML的操作,改变一个元素中的源代码,从而改变网页上显示的内容。也称为更改和删除 Document 网页文档等操作。进行 DOM 操作。
在上面的例子中,操作 document.getElementById(“myDiv”).innerHTML=xmlhttp.responseText 会将 ID 为 myDiv 的节点内部的 HTML 代码更改为服务器返回的内容,从而使服务器返回的新内容将显示在 myDiv 元素内。数据,部分页面似乎已更新。
可以看到,发送请求、解析内容、渲染网页这三个步骤实际上都是由 JavaScript 完成的。
回想一下微博的下拉刷新,其实就是一个JavaScript向服务器发送Ajax请求,然后获取新的微博数据,解析,呈现在网页中的过程。
因此,真正的数据实际上是通过一次又一次的ajax请求获得的。如果我们想捕获这些数据,我们需要知道这些请求是如何发送的,发送到哪里,发送了什么参数。如果我们知道这一点,难道我们不能用 Python 来模拟这个发送操作并得到结果吗?
阿贾克斯分析
这里我们还是以之前的微博为例。我们知道拖拽刷新的内容是通过ajax加载的,页面的url没有变化。这时候,我们应该去哪里查看这些Ajax请求呢?
这里还需要用到浏览器的开发者工具。下面是Chrome浏览器的介绍。
首先用Chrome浏览器打开微博链接,然后在页面上右击,在弹出的快捷菜单中选择“检查”选项,会弹出开发者工具,如图:
如前所述,这里是页面加载过程中浏览器和服务器之间发送请求和接收响应的所有记录。
Ajax 有其特殊的请求类型,称为 xhr。在图中,我们可以找到一个以getIndex开头的请求,其Type为xhr,是一个Ajax请求。用鼠标点击请求,查看请求的详细信息。
右侧可以看到Request Headers、URL、Response Headers等信息。Request Headers中的信息之一是X-Requested-With:XMLHttpRequest,将请求标记为Ajax请求,如图:
然后我们点击 Preview 可以看到响应的内容,是 JSON 格式的。在这里,Chrome 会自动为我们解析它。单击箭头可展开和折叠相应的内容。
我们可以观察到返回的结果是我的个人信息,包括昵称、简介、头像等,这也是用于渲染个人主页的数据。JavaScript 接收到数据后,执行相应的渲染方法,整个页面都被渲染出来了。
另外,我们还可以切换到Response选项卡,观察真实的返回数据,如图:
接下来,切换回第一个请求,观察它的Response是什么,如图:
这是原创链接返回的内容,不到 50 行代码,结构非常简单,只是执行了一些 JavaScript。
因此,我们看到的微博页面的真实数据并不是原创页面返回的,而是在执行完 JavaScript 后,再次向后台发送 Ajax 请求,浏览器获取数据并进一步渲染。
过滤请求
接下来,我们使用 Chrome DevTools 的过滤功能过滤掉所有的 Ajax 请求。请求上方有一层过滤栏,直接点击XHR,那么下面显示的所有请求都是Ajax请求,如图:
接下来继续滑动页面,可以看到页面底部有新的微博滑动,开发者工具下不断出现Ajax请求,这样我们就可以捕获所有的Ajax请求。
随意打开一个entry,可以清晰的看到它的Request URL、Request Headers、Response Headers、Response Body等,这时候模拟请求和提取就很简单了。
下图显示的内容是我的一个微博页面的列表信息:
至此,我们已经能够分析出一些Ajax请求的详细信息了。接下来,我们只需要用程序模拟这些Ajax请求,就可以很方便的提取出我们需要的信息了。
参考文章