Python编程—Ajax数据爬取(一)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Python编程—Ajax数据爬取(一)

Python编程—Ajax数据爬取
在浏览器中可以看到正常显示的页面数据,而使用requests得到的结果中并没有这些数据。这是因为requests获取的都是原始HTML文档,而浏览器中的页面是JavaScript处理数据后生成的结果,这些数据有多种来源:可能是通过Ajax加载的,可能是包含在HTML文档中的,也可能是经过JavaScript和特定算法计算后生成的。

对第一种来源,数据加载是一种异步加载方式,原始页面最初不会包含某些数据,当原始页面加载完后,会再向服务器请求某个接口获取数据,然后数据才会经过处理从而呈现在网页上,这其实是发送了一个Ajax请求。使得web开发做到前后端分离,减小服务器直接渲染页面带来的压力。

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

5.1 什么是Ajax
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。它基于 HTML、CSS、JavaScript、XML 和 XMLHttpRequest 等标准。

首先,AJAX 的全称是 Asynchronous JavaScript and XML(异步的JavaScript和XML),它是一种用于创建更好更快以及交互性更强的Web应用程序的技术。使用 JavaScript 向服务器提出请求并处理响应而不阻塞用户的核心对象是 XMLHttpRequest。

其次,AJAX 的主要优点是可以在不刷新整个网页的情况下,对网页的某部分进行更新。这样可以提高网页的响应速度和用户体验,因为它避免了每次用户操作都需要等待整个页面重新加载的情况。

最后,AJAX 的应用场景非常广泛,包括但不限于表单提交、数据检索、实时消息更新等。通过使用 XMLHttpRequest 对象和回调函数,可以实现局部刷新,从而检测用户输入的用户名是否为"zhongfucheng"。

实例引入
微博主页https://m.weibo.cn/u/2830678474为例。

基本原理
简单分为3步——发送请求、解析内容、渲染网页。
发送请求
JavaScript可以实现页面的各种交互功能,Ajax也不例外,它也是由JavaScript实现的,实现代码如下:

var xmlhttp;
if (window.XMLHttpRequest) {
   
    xmlhttp = new XMLHttpRequest();
}else {
   //code for IE6、IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function () {
   
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
   
        document.getElementById("myDiv").innerHTML = xmlhttp.responsetext;
    }
}
xmlhttp.open('POST','/ajax/', true);
xmlhttp.send();

这是JavaScript对Ajax最底层的实现,实际上是先建一个XMLHttpRequest对象xmlhttp,然后调用onreadystatechange属性设置监听,最后调用open和send方法向某个链接(服务器)发送请求。这里的请求发送由JavaScript完成,不是Python实现。由于设置了监听,所以当服务器返回响应时,onreadystatechange对应的方法便会被触发,然后在这方法里面解析响应内容即可。

解析内容
服务器返回响应后,onreadystatechange属性对应的方法就触发了,此时利用xmlhttp的responseText属性便可得到响应内容。这类似于Python中利用requests向服务器发起请求,然后得到响应的过程。返回内容可能是HTML,可能是JSON,接下来只需在方法中用JavaScript进一步处理即可。如果是JSON的话,可以进行解析和转化。

渲染网页
JavaScript有改变网页内容的能力,因此解析完响应内容后,就可以调用JavaScript来基于解析完的内容对网页进行下一步处理了。例如,通过document.getElementById().innerHTML操作,可以更改某个元素内的源代码,这样网页显示的内容就改变了。这种操作也被称为DOM操作,即对网页文档进行操作,如更改、删除等。

上面“发送请求”部分,代码里的document.getElementById(”myDiv”).innerHTML=xmlhttp.responseText便是将ID为myDiv的节点内部的HTML代码更改为服务器返回的内容,这样myDiv元素内部便会呈现服务器返回的新数据,对应的网页内容看上去就更新了。

5.2 Ajax分析方法
分析案例
用Chrome浏览器打开微博链接https://m.weibo.cn/u/2830678474,然后在页面中单击鼠标右键,从弹出的快捷菜单中选择“检查”选项,此时便会弹出开发者工具,如图所示:

image.png
image.png

Ajax尤其特殊请求类型叫做xhr,可以发现一个名称以getIndex开头的请求,其Type就为xhr,意味着这就是一个Ajax请求。用鼠标单击这个请求,可以查看其详细信息。其中Request Headers中有一个信息为X-Rrequested-With:XMLHttpRequest,这就标记了此请求是Ajax请求,如图所示:

image.png

随后单击一下Preview, 就能看到响应内容,如图所示,内容是JSON格式的,这里Chrome为我们自动做了解析,单击左箭头即可展开和收起相应内容。
image.png

经过观察可以发现,这里的返回结果是我的个人信息,如昵称、简介、头像等,这也是渲染个人主页使用的数据。JavaScript接收到这些数据之后,再执行相应的渲染方法,整个页面就渲染出来。
image.png

也可以切换到Response选项卡,从中观察真实的返回数据,如图所示:

image.png

接下来,切回第一个请求,观察一下它的Response是什么,如图所示:

image.png

原始的链接https://m.weibo.cn/u/2830678474返回的结果,其代码只有不到50行,结构也非常简单,只是执行了一些JavaScript语句。所以说,微博页面呈现给我们的真实数据并不是最原始的页面返回的,而是执行JavaScript后再次向后台发送Ajax请求,浏览器拿到服务器返回到数据后进一步渲染得到的。

1.过滤请求
利用Chrome开发者工具的筛选功能能够筛选出所有Ajax请求。在请求的上方有一层筛选栏,直接单击XHR,之后下方显示的所有请求便都是Ajax请求了,如图所示:

image.png

接下来只需要用程序模拟这些Ajax请求,就可以轻松提取我们所需的信息。

5.3 Ajax分析与爬取实战
准备工作

  1. 安装好Python3(最低为3.6版本),并成功运行Python3程序。
  2. 了解Python HTTP请求库requests的基本用法。
  3. 了解Ajax基础知识和分析Ajax的基本方法。

爬取目标
示例网站链接:https://spa1.scrape.center/,该示例网站的数据请求是通过Ajax完成的,页面的内容是通过JavaScript渲染出来的,页面如图所示。

image.png

单击每部电影进入对应的详情页,这些页面的结构也是完全一样的,如下图所示的是《迁徙的鸟》的详情页。

image.png

完成目标如下:

  1. 分析页面数据的加载逻辑
  2. 用requests实现Ajax数据的爬取
  3. 将每部电影的数据分别保存到MongoDB数据库

初步探索
先尝试用requests直接提取页面,看看结果。实现代码如下:

import requests

url = '<https://spa1.scrape.center/>'
html = requests.get(url).text
print(html)

运行结果如下:
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge">
<meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title>Scrape | Movie</title>
<link href=/css/chunk-700f70e1.1126d090.css rel=prefetch><link href=/css/chunk-d1db5eda.0ff76b36.css rel=prefetch>
<link href=/js/chunk-700f70e1.0548e2b4.js rel=prefetch><link href=/js/chunk-d1db5eda.b564504d.js rel=prefetch>
<link href=/css/app.ea9d802a.css rel=preload as=style><link href=/js/app.17b3aaa5.js rel=preload as=script>
<link href=/js/chunk-vendors.683ca77c.js rel=preload as=script><link href=/css/app.ea9d802a.css rel=stylesheet>
</head><body><noscript><strong>We're sorry but portal doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript><div id=app></div><script src=/js/chunk-vendors.683ca77c.js></script><script src=/js/app.17b3aaa5.js></script>
</body></html>

可以看到,爬取结果只有这么一点HTML内容,在HTML中只能看到源码引用的一些JavaScript和CSS文件,没有观察到任何电影数据信息。这说明浏览器执行了HTML中引用的JavaScript文件,通过调用一些数据加载和页面渲染方法,才最终呈现页面显示的结果。JavaScript在后台调用Ajax数据接口,得到数据之后,再对数据进行解析并渲染呈现出来。所以直接爬取Ajax接口,再获取数据就好了。

接下文 Python编程—Ajax数据爬取(二)https://developer.aliyun.com/article/1620693

相关文章
|
1天前
|
数据采集 存储 监控
如何使用 Python 爬取商品数据
如何使用 Python 爬取京东商品数据
15 3
|
1天前
|
开发者 Python
Python 语法糖:让编程更简单
Python 语法糖:让编程更简单
14 3
|
1天前
|
开发者 Python
Python 语法糖:让编程更简单(续)
Python 语法糖:让编程更简单(续)
12 3
|
1天前
|
人工智能 数据挖掘 程序员
Python 编程入门:打造你的第一个程序
【10月更文挑战第3天】编程,这个看似高深莫测的技能,实际上就像学骑自行车一样,一旦掌握,便能开启全新的世界。本文将带领初学者步入Python编程的殿堂,从基础语法到编写实用程序,一步步解锁编程的乐趣。
|
1天前
|
数据采集 存储 监控
如何使用 Python 爬取京东商品数据
如何使用 Python 爬取京东商品数据
11 2
|
1天前
|
小程序 Python
利用Python编程提取身份证的信息
利用Python编程提取身份证的信息
10 2
|
1天前
|
数据采集 前端开发 NoSQL
Python编程异步爬虫实战案例
Python编程异步爬虫实战案例
10 2
|
1天前
|
Python
Python 语法糖:让编程更简单(续二)
Python 语法糖:让编程更简单(续二)
12 1
|
1天前
|
存储 开发者 Python
Python 编程入门:从基础到实战
【10月更文挑战第3天】本文将引导你进入 Python 编程的奇妙世界,从零基础开始,逐步深入到编程实践。我们将一起探索 Python 的基本语法、数据结构、函数和模块的使用,以及面向对象编程的概念。通过实际案例,你将学会如何应用这些知识解决实际问题,并最终能够独立编写简单的 Python 程序。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供一个坚实的起点。
8 1
|
2天前
|
Android开发 Swift iOS开发
python 基于电脑蓝牙连接获取手机的实时数据
python 基于电脑蓝牙连接获取手机的实时数据
7 0