ajax抓取网页内容(什么是Ajax有时候我们使用浏览器查看页面得到的数据不一致 )
优采云 发布时间: 2021-10-26 18:17ajax抓取网页内容(什么是Ajax有时候我们使用浏览器查看页面得到的数据不一致
)
一、什么是 Ajax
有时我们使用浏览器查看页面正常显示的数据与使用请求抓取页面获取的数据不一致。这是因为获取的请求是原创的 HTML 文档,浏览器中的页面是 JavaScript 处理数据的结果。这些数据可能通过Ajax加载,可能收录在HTML文档中,也可能通过特定算法计算生成。
Ajax,全称是AsynchronousJavaScriptandXML,即异步JavaScript和XML。它是一种使用 JavaScript 来确保页面不刷新和连接保持不变的技术。服务器交换数据并更新一些网页。
1.示例
在浏览网页时,我们发现很多网页已经向下滚动以查看更多选项。以新浪微博首页为例。一直往下滑,看了几条微博就消失了。取而代之的是一个加载*敏*感*词*,很快就出现了新的微博内容。这个过程就是Ajax加载的过程,如下图:
2.基本原则
向网页更新发送ajax请求的过程可以简单分为三步:
1.发送请求
2.分析内容
3. 渲染页面
♦ 发送请求
var xmlhttp;
if (window.XMLHttpRequest) {
// IE7,Firefox,Chrome,Safari,opera
xmlhttp = new XMLHttpRequest()
} else {
// IE6,IE5
xmlhttp = new ActiveXObject(\'Microsoft.XMLHTTP\');
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("content").innerHTML = xmlhttp.responseText;
}
};
xmlhttp.open(\'POST\', \'/ajax\', true);
xmlhttp.send()
这是使用 JavaScript 的 Ajax 的低级实现。其实就是新建一个 XMLHttpRequest 对象,然后调用 onreadystatechange 实现设置*敏*感*词*,然后使用 open() 和 send() 方法向一个连接(也就是服务器)发送请求。当响应返回时,触发相应的*敏*感*词*方法,解析响应内容。
♦分析内容
onreadystatechange对应的属性触发后,使用xmlhttp的responseText属性获取响应内容。
♦呈现网页
解析响应后,通过document.getElementById("content").innerHTML等方法改变某个元素内部的HTML代码,从而呈现网页。这种操作也称为DOM操作,即对Document的操作。
因此,我们知道真实的数据是从一次又一次的 Ajax 请求中获取的。如果你想抓取这些数据,你需要知道这些请求是如何发送的。然后用Python模拟发送操作,得到结果。
二、ajax方法解析1.查看请求
使用Chrome浏览器访问新浪微博首页,打开开发者工具。切换到网络选项卡,再次刷新页面,看到很多条目。
Ajax 请求实际上有其特殊的请求类型,称为 xhr。在途中对应的Type请求类型中,点击图中的XHR,过滤掉所有的xhr请求。找到其中一个 xhr 请求并单击以查看详细信息。RequestHeaders 中的一条信息是 X-Requested-With:XMLHttpRequest,它将请求标记为 Ajax 请求。如下所示
3.ajax结果抽取1.请求分析
使用开发者工具打开Ajax的XHR过滤器,然后向下滑动页面,我们会看到有不断的Ajax请求。选择其中一个请求,分析其参数信息,输入请求详情。如下所示:
可以发现这是一个GET请求,url为ajwvr=6&category=0&page=3&lefnav=0&cursor=&__rnd=65。有六个请求的参数:ajwvr、category、page、lefnav、cursor、__rnd。
查看其他请求,发现只有page和__rnd这两个参数在变化。很明显page是用来控制分页的,仔细观察__rnd的值对应的是时间戳。
2.分析响应
观察这个请求的响应内容:
该内容的格式为JSON,主要内容在data对应的值中。这样我们就请求了一个接口,改变了页面参数来获取对应的数据。
3. 爬取数据
这里我们要模拟本剧的ajax请求,向下爬取前10页的数据。
# _*_ coding=utf-8 _*_
import requests, time
from urllib.parse import urlencode
base_url = \'https://weibo.com/a/aj/transform/loadingmoreunlogin?\'
headers = {
\'Host\': \'weibo.com\',
\'Referer\': \'https://weibo.com/\',
\'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36\',
\'X-Requested-With\': \'XMLHttpRequest\',
}
def get_page(page):
"""
:param page:
:return:
"""
# 构造__rnd参数
rnd = int(time.time())
# 构造参数字典
params = {
\'ajwvr\': \'6\',
\'category\': \'0\',
\'page\': page,
\'lefnav\': \'0\',
\'cursor\': \'\',
\'__rnd\': rnd
}
# 拼接参数与url
url = base_url + urlencode(params)
try:
res = requests.get(url, headers=headers)
if res.status_code == 200:
return res.json()
except Exception as e:
print(\'Error:\', e.args)
def parse(res):
weibo = {}
if res:
weibo[\'data\'] = res.get(\'data\')
yield weibo
if __name__ == "__main__":
for page in range(1, 11):
result = get_page(page)
weibo_data = parse(result)
for data in weibo_data:
print(data)
查看代码
操作结果:
{\'data\': \' \n \r\n\r\n \r\n \r\n <a href="/a/hot/7562265474177025_1.html?type=new" target="_blank" suda-uatrack="key=www_unlogin_home&value=focus01">\r\n
头条新闻今日快讯 | 华为在美提起诉讼.....}这样我们就可以通过分析Ajax请求和编写爬虫来获取微博数据。当然,代码可以更优化,可以解析具体的标题和内容。这里只是演示Ajax请求的模拟过程,爬取结果不是重点。