有些时候,我们直接通过网络请求库请求网页地址时,得到的响应结果可能跟浏览器中右键查看网页源码所看到的内容不一样。例如,在抓取:https://www.feeair.com/threeCode.html (飞啊网)这个网页时,通过浏览器看到的页面数据是正常的,但是通过 requests库直接去请求这个地址,返回的网页源代码数据和在浏览器上看到的是不同的。

这是为什么呢?实际上,这是因为 requests 获取到的都是原始的 HTML 文档,而浏览器中的页面是经过 JavaScript 处理数据后生成的结果,这些数据来源有多种,可能是通过 Ajax 加载的,也可能是包含在 HTML 文档中的,还有可能是经过 JavaScript 和特殊的算法计算后生成的。对于第一种情况,数据加载是一种异步加载方式,原始的页面最初不会包含某些数据,原始页面加载完成后,再通过 JS 向服务器发送一个或多个请求获取数据,数据才会被处理并呈现在网页上,这其实就是发送了一个 Ajax请求。

Ajaxe简介

Ajax 的全称为 Asynchronous JavaScript and XML,即异步的 JavaScript 和 XML,它不是新的编 程语言,而是一种使用现有标准的新方法,它可以在不重新加载整个页面的情况下与服务器交换数据并更新部分网页的数据。在 W3School 网站上也有几个关于 Ajax 的小实例,有兴趣的读者可以打开网址 http://www.w3school.com.cn/tiy/t.asp?f=ajax_get 去体验一下。

实例引入

下面通过一个实例来了解 Ajax 请求,这里以前面提到的“飞啊网”为例,在浏览器中打开链接,如图1所示。

飞啊网首页地址:https://www.feeair.com/threeCode.html

图1 飞啊网首页

在页面上的“三字代码查询”输入框中输入“PEK”,然后点击【查询】按钮将会出现如图2所示的搜索结果。

图2 搜索结果

得到查询结果后仔细观察查询前和查询后的页面,特别是 URL 地址栏,可以发现查询前和查询后页面的 URL 没有任何变化,但下面的列表中的数据却不一样了,这其实就是 Ajax 的效果,在不刷新全部页面的情况下,通过 Ajax 异步加载数据,实现数据局部更新。

Ajax的基本原理

初步了解了 Ajax 之后,下面再来详细了解它的基本原理。发送 Ajax 请求到网页更新的过程可以简单地分为以下 3 个步骤。

  1. 发送请求
  2. 解析返回数据
  3. 渲染数据到网页

在具体讲解这 3 个步骤之前,可以先看一下它的抽象过程图,如图3所示。

图3 ajax抽象原理图

1.发送请求

我们知道,JavaScript 可以实现页面的各种交互功能。Ajax 也不例外,它的底层也是由 JavaScript 实现的。要使用 Ajax 技术,需要先创建一个 XMLHttpRequest 对象,缺少它就不能实现异步传输。所以执行 Ajax 时,实际上需要执行以下代码。

var xmlhttp;
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xmlhttp=new XMLHttpRequest();
}else {
// IE6, IE5 浏览器执行代码
xmlhttp=new ActtveXObject("Microsott.XMLHTTP");
}
xmlhttp.open("GET","/try/ajax/demo_get2.php?fname=Henry&lname=Ford",true);
xmlhttp.send();
xmlhttp.open("POST","/try/ajax/demo_post2.php",true);
xmlhttp.setRequestHeader("Content-type","applicatton/x-www-form-urlen coded");
xmlhttp.send("fname=Henry&lname=Ford");

在网页中为某些事件的响应绑定异步操作:通过上面创建的 xmlhttp 对象传输请求、携带数据。 在发出请求前要先定义请求对象的 method、要提交给服务器中哪个文件进行请求的处理、要携带 哪些数据,以及判断是否异步。

其中,与普通的 Request 提交数据一样,这里也分两种方式:GET 和 POST,在实际使用时可根据需求自主选择。GET 和 POST 都是向服务器提交数据,并且都会从服务器获取数据。它们之间的区别如下。

  1. 传送方式:GET 通过地址栏传输,POST 通过报文传输。
  2. 传送长度:GET 参数有长度限制(受限于 URL 长度),而 POST 无限制。

对于 GET 方式的请求,浏览器会把 HTTP header 和 data 一并发送出去,服务器响应 200(返回数据);而对于 POST,浏览器先发送 header,服务器响应 100 continue,浏览器再发送 data,服务器响应 200 OK(返回数据)。也就是说,GET 只需要汽车跑一趟就把货送到了,而 POST 得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。因为 POST 需要两步,时间上消耗的要多一点,看起来 GET 比 POST 更有效。 因此推荐用 GET 替换 POST 来优化网站性能。

2.解析返回数据

服务器在收到请求后,就会把附带的参数数据作为输入传给处理请求的文件,例如,前面代码中所示:把 fname=Henry&lname=Ford 作为输入,传给“/try/ajax/demo_get2.php”文件。然后该文件根据传入的数据做出处理,最终返回结果,并通过 Response 对象发回去。客户端根据 xmlhttp 对象来获取 Response 的内容,返回的 response 内容可能是 HTML 也可能是 JSON,接下来只需要在方法中用 JavaScript 做进一步的处理即可。例如,当为 JSON 时可以进行解析和转化。

例如,这里使用谷歌浏览器打开前面的飞啊网后,按【F12】 键打开调试模式,然后在页面的搜索框中输入“PEK”并单击【搜索】按钮。之后在调试面板中切 换到【Network】选项卡,找到名称为 getAirInfo 的请求并单击即可以查看 Ajax 发起请求之后返回的 JSON 数据,如图 4所示。

图4 请求响应结果

3.渲染网页

JavaScript有改变网页内容的能力,所以在通过 Ajax 请求获取到返回数据后,通过解析就可以调用指定的网页DOM对象进行更新、修改等数据处理了。例如,通过 document.getElementById().innerHTML 操作,便可以对某个元素内的元素进行修改,这样网页显示的内容就改变了,这样的操作也被称为 DOM 操作,即对 Document 网页文档进行操作,如修改、 删除等。

Ajax方法分析

这里仍以飞啊网为例,我们都知道在条件筛选框中输入机场三字码时刷新内容由 Ajax 加载,而且页面的 URL 没有变化,那么应该到哪里去查看这些 Ajax 请求呢?前面小节其实有简单提到,但是笔者这里还是要重新详细讲解下。

这里需要借助浏览器的开发者工具,下面以 Chrome 浏览器为例来介绍。

步骤1:用 Chrome 打开网址:https://www.feeair.com/threeCode.html

步骤2:在页面中右击,在弹出的快捷菜单中选择【检查】选项或按【F12】键,此时会弹出开发者工具,如图 5 所示,在【Elements】选项卡中会显示网页的源代码,其下方是节点的样式。不过这不是我们想要寻找的内容。

步骤3:切换到【Network】选项卡,重新刷新当前页面,可以发现这里出现了非常多的条目, 其实这些条目就是页面在加载过程中浏览器与服务器之间发送请求和接收响应的所有记录,如图6 所示。

图5

图6 network选项卡

Ajax 有其特殊的请求类型,它叫作 xhr。图 7 中用矩形框起来的部分,可以发现有一个名称为“getAirInfo”的请求,其 Type 为 xhr,这就是一个名副其实的 Ajax 请求。单击这个请求就可以看到它的详细信息。

图7 getAirInfo请求信息

步骤4:单击【getAirInfo】请求,会看到右侧有它的一些详细信息,如图 8 所示,这里有 5 个选项卡,选择【Preview】或【Response】选项卡就会看到当前 Ajax 请求向服务器端发起请求后服务器端响应的内容了。得到这些内容后,JS 就可以解析处理,将它更新到网页中。

图8 响应结果

在进行请求分析时,若发现条目太多,不方便直接找出xhr方法时,这里教大家一个小技巧: 单击图9中的【Type】选项,就可以快速地对请求进行筛选分类,这时再按分类去查找xhr就快速多了。

图9 筛选请求条目

使用Python网络请求库发起请求获取数据

在前面的分析中,已经找到到了一个名为“getAirInfo”的请求返回了查询的机场信息,接下来需要进一步分析它的请求参数然后使用Python的网络请求库来发起请求获取数据。

通过浏览器抓包找到“getAirInfo”请求后,直接单击它一下,这时候看到【Headers】下面有很多关于请求的详细信息,例如:

  1. 请求链接 Request URL 为:https://www.feeair.com/wp-json/myapi/getAirInfo
  2. 请求的方法Request Method为:POST

继续拖动滚动条到最下方 From Data 处,可以看到这里有三个参数:condition、page_no和page_size分别对应的含义是:要查询的三字码、页码、每页显示的大小。除此之外,还传递了一些请求头信息,如图10中的Request Headers。

图10 请求头信息

接着看看它的响应结果是什么样的。选择【Preview】选项卡,将会出现如图 11 所示的内容,这些内容是 JSON 格式,浏览器开发工具自动做了解析方便查看。可以看到有 6 个信息,分别是:

  1. SUCCESS:表示请求是否成功
  2. TotalCount:查询的总数
  3. TotalPage:总页数
  4. airInfoList:基础信息列表
  5. pageNo:页码
  6. status:请求状态码

新手读者需要注意的是,这6个响应信息不是固定的,每个网站或每个不同的请求响应的内容都不一样。

图11 响应结果

编写Python代码获取数据

下面使用 Python 的 requests 库编写代码来模拟抓取。首先在代码中定义出要请求的URL地址和请求需要提交的参数信息,然后再引入requests库进行请求获取数据。示例代码如下:

import requestsurl = "https://www.feeair.com/wp-json/myapi/getAirInfo"
data = {"condition": "pek","page_no": "1","page_size": "30"
}
resp = requests.post(url, data=data).json()
print(resp)

运行结果如下:

{"TotalCount": 0,"TotalPage": 0,"pageNo": 1,"airInfoList": [{"id": "3376","code": "PEK","icao": "ZBAA","airport_name": "Beijing Capital International Airport 北京首都国际机场","city": "Beijing 北京市","area": "Beijing 北京","country": "China 中国 (CN)","time_zone": "+08:00","continent": "Asia","airport_type": "海关机场","longitude": "40.0798573","dimention": "116.6031121","bank_interest": "Open on Saturday, closed on Sunday.","url": "/cn/code/beijing_capital_international_airport_pek.html","star": "4","yj_num": "6","update_time": "2019-07-03 10:16:45","type": 1}],"status": 1,"SUCCESS": true
}

通过上述方法成功得到了关于北京首都机场的相关信息,另外,还可以增加一个方法,用于将数据保存到数据库中或Excel中等。

新手问答

1.为什么有些 Ajax 接口在模拟了它的参数请求之后却抓取不到数据?

答:首先这里需要了解的一点就是,现在很多网站是有反爬策略的,也就是说,它不想让别人 通过爬虫获取到它的数据,所以采取了一些手段,如对接口的参数加密、IP 访问频率控制等。遇 到这种问题,很可能是你模拟的接口中有些参数是需要加密或用别的特殊方法获取值携带到请求中 的,如 tooken 之类的。遇到这种网站就需要进一步地分析它的参数或换思路爬取。

2.Ajax 接收到的数据类型是什么?

答:后台返回的数据主要有 3 种类型:String、JSON 串和 JSON 对象。接收到了这 3 种类型的 数据,可以通过 JSON 对象直接循环使用、JSON 串转 JSON 使用和 String 直接使用。具体方式可 根据实际得到的数据来选择。

Ajax请求原理与数据抓取相关推荐

  1. 爬虫(爬虫原理与数据抓取)

    爬虫(爬虫原理与数据抓取) 通用爬虫和聚焦爬虫 根据使用场景,网络爬虫可分为 通用爬虫 和 聚焦爬虫 两种. 通用爬虫 通用网络爬虫 是 捜索引擎抓取系统(Baidu.Google.Yahoo等)的重 ...

  2. python爬虫之Ajax动态加载数据抓取--豆瓣电影/腾讯招聘

    动态加载数据抓取-Ajax 特点 1.右键 -> 查看网页源码中没有具体数据 2.滚动鼠标滑轮或其他动作时加载 抓取 1.F12打开控制台,页面动作抓取网络数据包 2.抓取json文件URL地址 ...

  3. 爬虫—01-爬虫原理与数据抓取

    爬虫的更多用途 12306抢票 网站上的头票 短信轰炸 关于Python网络爬虫,我们需要学习的有: Python基础语法学习(基础知识) 对HTML页面的内容抓取(数据抓取) 对HTML页面的数据提 ...

  4. 关于Python爬虫原理和数据抓取1.1

    为什么要做爬虫? 首先请问:都说现在是"大数据时代",那数据从何而来? 企业产生的用户数据:百度指数.阿里指数.TBI腾讯浏览指数.新浪微博指数 数据平台购买数据:数据堂.国云数据 ...

  5. python爬虫百度百科-python爬虫(一)_爬虫原理和数据抓取

    本篇将开始介绍Python原理,更多内容请参考:Python学习指南 为什么要做爬虫 著名的革命家.思想家.政治家.战略家.社会改革的主要领导人物马云曾经在2015年提到由IT转到DT,何谓DT,DT ...

  6. 爬虫的原理和数据抓取

    为什么要做爬虫? 都说现在是"大数据时代",那数据从何而来? 企业产生的用户数据:百度指数.阿里指数.TBI腾讯浏览指数.新浪微博指数 数据平台购买数据:数据堂.国云数据市场.贵阳 ...

  7. 爬虫原理与数据抓取----- Requests模块

    Requests: 让 HTTP 服务人类 虽然Python的标准库中 urllib2 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 & ...

  8. 爬虫原理与数据抓取----- urllib2:URLError与HTTPError

    urllib2 的异常错误处理 在我们用urlopen或opener.open方法发出一个请求时,如果urlopen或opener.open不能处理这个response,就产生错误. 这里主要说的是U ...

  9. python爬虫从入门到实战笔记——第一章爬虫原理和数据爬取

    爬虫原理和数据抓取 1.1 通用爬虫和聚焦爬虫 通用爬虫 聚焦爬虫 1.2 HTTP和HTTPS HTTP的请求与响应 浏览器发送HTTP请求的过程: 客户端HTTP请求 请求方法 常用的请求报头 服 ...

最新文章

  1. 如何在 CentOS 7 中安装或升级最新的内核
  2. 【深度学习入门到精通系列】Python批量实现图像镜像翻转
  3. java mvc 实际分层_SpringMVC体系分层模式原理图解
  4. TensorFlow实战-AlexNet
  5. 使用jasmine.createSpyObj具有依赖关系的Angular服务进行单元测试
  6. 如何快速弄懂一个新模型_如何评估创业项目是否靠谱?一个新的模型 | 创创锦囊...
  7. 美国计算机专业硏究生,2014年美国计算机专业研究生排名
  8. python定义字体颜色_windows print 自定义字体颜色【python】
  9. Unity3D实现按钮切换Panel的功能
  10. c#解析XML到DATASET及dataset转为xml文件函数
  11. 猎隼涉密计算机安全,[原创]如何干掉《“猎隼”涉密计算机上网监察取证系统》...
  12. 计算机基础中关于二进制,计算机基础二进制十进制.ppt
  13. php 网站的多语言设置(IP地址区分国内国外)
  14. 学计算机选择师范类好吗,师范教育类专业和计算机类专业,两者相比,哪个更适合自考生报读...
  15. K3S执行命令提示You must be logged in to the server (Unauthorized)
  16. 【华为OD机试真题 JS】统计射击比赛成绩
  17. Week8 CSP模拟 T2 HRZ学英语
  18. Guided Anchor论文笔记
  19. 关于gluster分布式哈希研究
  20. 旋转卡壳算法(转载)

热门文章

  1. ESP定律和堆栈平衡
  2. 微信小程序知识点(二)
  3. 给自己找个开心的理由
  4. 身份证前六位地区码对照表(最全版)
  5. 有过裸辞经历的人会影响找工作吗?
  6. stanley 轨迹跟踪算法
  7. 用洋葱架构实现领域驱动设计
  8. 收到陌生短信千万不要随意打开网址,小心窃取你的账号密码-速码云
  9. Failed to transform artifact ‘support-v4.aar (com.android.support:support-v4:22.0.0)‘ to match attri
  10. 大学毕业从事短视频剪辑是否有前途?