爬虫:Ajax数据爬取

本文介绍了Ajax数据爬取的原理和方法。Ajax是一种利用JavaScript实现的异步数据加载技术,使得页面在不刷新的情况下更新内容。在爬取此类网页时,需要分析并模拟Ajax请求。通过Chrome开发者工具查看和过滤xhr类型的请求,提取请求参数和响应内容,然后使用Python等工具模拟Ajax请求以获取所需数据。
摘要由CSDN通过智能技术生成

目录

1、什么是Ajax

1.1 实例的引入

1.2 基本原理

2、Ajax分析方法

1、查看请求

 2、过滤请求

3、Ajax结果提取

1、分析请求

2、分析响应

3、例子


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

对于第一种情况,数据加载是一个中异步加载方式,原始的页面最初不会包含某些数据,原始页面加载完后,会再向服务器请求某个接口获取数据,然后数据才被处理从而呈现到网页上,这其实就是发送了一个Ajax请求,这种形式的页面原来越多,网页的原始HTML文档不会包含任何数据,数据都是通过Ajax统一加载后在呈现出来的,这样在Web开发上可以做到前后端分离,而且降低服务器直接渲染页面带来的压力

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

1、什么是Ajax

Ajax ,全称为 Asynchronous JavaScript and XML ,即异步的 JavaScript 和XML 它不是一门编程 语言,而是利用 JavaScript 在保证页面不被刷新、页面链接不改变的情况下与服务器交换数据并更新部分网页的技术。

对于传统的网页,如果想更新其内容,那么必须要刷新整个页面,但有了 Ajax ,便可以在页面不 被全部刷新的情况下更新其内容 在这个过程中,页面实际上是在后台与服务器进行了数据交互,获取到数据之后,再利用 JavaScript 该变网页,这样网页内容就会更新了

1.1 实例的引入

浏览网页的时候,我们会发现很多网页都有下滑查看更多的选项: 比如我个人CSDN的主页, 再向下就没有了,转而会出现一个加载的动间,不一会儿下方就继续出现了新的CSDN内容,这个过程 真实就是 Ajax 加载的过程

我们注意到页面其实并没有整个刷新,也就意味着页面的链接没有变化,但是网页中却多了新内 容,也就是后面刷出来的CSDN 这就是通过 Ajax 获取新数据’并呈现的过程

1.2 基本原理

发送Ajax请求到网页更新的这个过程可以简单分为以下3步

  1. 发送请求
  2. 解析内容
  3. 渲染网页

1、发送请求

JavaScript 可以实现页面的各种交互功能, Ajax也不例外,它也是由 JavaScript 实现的, 实际上执行了如下代码:

var xmlhttp;
if (window.XMLHttpRequest) {
        // code for IE7+ , Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
} else {// code for IE6, IES
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
} 
xmlhttp.onreadystatechange=function() {
    if (xmlhttp.ready5tate==4 && xmlhttp.status==200) {
    document.getElementById ("myDiv").innerHTML=xmlhttp.responseText;
    }
}
    xmlhttp.open("POST","/ajax/", true);
    xmlhttp.send();

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

2、解析内容

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

3、渲染网页

JavaScript有改变网页内容的能力,解析完响应内容之后,就可以调用 JavaScript来针对解析完的 内容对网页进行下一步处理了, 比如,通过 document.getElementByid().innerHTML这样的操作,便可以对某个元素内的源代码进行更改,这样网页显示的内容就改变了,这样的操作也被称作 DOM 操作, 即对 Document 网页文档进行操作,如更改、删除等;

上例中, document.getElementByid("myDiv ").innerHTML=xmlhttp.responseText便将ID为 myDiv 的节点内部的HTML代码更改为服务器返回的内容,这样myDiv元素内部便会呈现出服务器返回的 数据,网页的部分内容看上去就更新了

这3个步骤其实都是由JavaScript完成的,它完成了整个请求,解析,和渲染的过程

真是的数据其实都是一次次的Ajax请求得到的,如果想要抓取这些数据,需要直到这些请求到底怎么发送的,发往哪里,发了哪些参数,如果我们直到了这些,就可以用Python模拟这个发送操作,获取到其中的结果了?

2、Ajax分析方法

拖动刷新的内容由Ajax加载,而且页面的URL没有变化,那么我们到哪里去查看这些Ajax请求?

1、查看请求

这里我们就需要Chrome浏览器开发者工具来,切换到Network选项卡,我们知道页面加载过程中浏览器与服务器之间发送请求和接受响应的记录

Ajax其实有其特殊的请求类型,叫做xhr,我们可以看到这个get-tab-total请求就是Ajax请求

 有的请求中,Request Headers、URL和Response Headers等信息,其中Request Headers中有一个信息为X-Requested-With:XMLHttpReqest,这就标记了此请求时Ajax请求,

点击Preview,我们可以看到响应的响应的内容,它是JSON格式的,这里chrome为我们做了自动解析,我们可以发现返回的时文章的信息,这也是用来渲染个人主页所使用的数据,JavaScript接受到这些数据之后,再执行相应的渲染方法,整个页面就渲染出来了
 

我们看下第一个请求,返回的其代码不是很多,结构也简单,只是执行了一些JavaScript,真是数据并不是最原始的页面返回的,而是后来执行JavaScript后,再次向后台发送了Ajax请求,浏览器拿到数据后进一步渲染出来的

 2、过滤请求

使用Chrome开发工具筛选共嗯那个选出所有的Ajax请求,在请求的商法选栏,直接点击XHR,此时在下方显示所有请求便是Ajax请求了

 我们点开一个请求就可以看到其:RequestURL,ReqestHeaders,ResponseHeader,Response Body等内容,此时我们模拟请求和提取就非常简单了

3、Ajax结果提取

以自己的CSDN为例子

1、分析请求

打开Ajax的XHR过滤器,选中其中一个请求,查看它参数信息;这是一个get请求,请求参数5个

 通过发现,请求的参数中始终为这5个,只是该表了page,这个参数只是用来控制分页的

2、分析响应

查看返回的响应,这个内容时JSON格式的,浏览器开发这工具自动做了解析所以方便我们查看,

 这些我们请求一个接口,就可以得到20天数据,而且请求只需要该表page参数既可

3、例子

获取自己CSDN的Ajax数据

from   urllib.parse import urlencode
import requests
from pyquery import PyQuery as pq
base_url = "https://blog.csdn.net/community/home-api/v1/get-business-list?"
headers = {
"cookie": "uuid_tt_dd=10_37481457760-1614696081762-771893; UN=Smart_look; Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=6525*1*10_37481457760-1614696081762-771893!5744*1*Smart_look; Hm_lvt_e5ef47b9f471504959267fd614d579cd=1620037344; __gads=ID=b2b2ba9fbd5f97fa-228d5d7c93cb004f:T=1631355448:RT=1631355448:S=ALNI_MaN-YuGZ0ZKrwQlnce2q2uTVYcQrQ; ssxmod_itna=Yq0h0K4Axx7tGH3iQ0gxQqAITqyDUEhTq874Y5dD/I3xnqD=GFDK40oAOIKuIx==YD8aiQFnADcfhq81RgxWd5n7cjxqGCe0aDbqGk7nzx4GGUxBYDQxAYDGDDPDoxKD1D3qDkD7g1ZlndtDm4GWzqGfDDoDYS6nDitD4qDB+2dDKqGgzwrXGeNQ6qqKv7+yD0t=xBd=F6hyAmaHk0NKocWjDxDHf8yo8Ah1rg443CpnDB6mxBQZ0MN00CHgDCX4=rhaKixYSEG69z4rKDPqeb4T5hD=KBDi9S4W/DqudE+zR5DADU44QOD4D===; ssxmod_itna2=Yq0h0K4Axx7tGH3iQ0gxQqAITqyDUEhTq874Y5G9Wv7DBTkAx7p+x8=QnhyoS8GlrMviCP5KQo=wDO/4w=85G3piamrVr=3th8s9p7XsBA/TE4+NN/l5R9W2Ee=Mc4LNE2L8YLdjNkUS=+U3i=IGXcIB3D8EUTWl5WzEr4Ar=480rZRov3v7d8CePQv4n8+bA5TZoFEraWhcaiULRdZfbcifrcWfr0AfHvFaq+LCtHVqnwsnoQbjKvvA5vLOD=WDO88nQPx9aCSFOUucO0H=3nOzCDgIH2=Hl67yls8vgsvVoEdkX/2eKWncBDu/xx7m9Dvlm+00hZIaSQpM+a=tDVIBifPzQcOI+kle5wcNWwM3E+Ww5=IhSBitgc07P6PQ15b4W=62VIg8I2b0oKtG3D07UYb1bxh0K8AN30AmQE7M8qGQcGqcSqHbxsGQV0f08T97DWSA+PFT07Sok/GmpP8KkfqfK=Z+YZ+YG8LPTqGUNYjADDLxD2/yWMgPBq4l2xnFqAKzDhKBqYKmKAnI0TAS2Y0QzkDPFdnBuzgTIZ2DDWTZhKQexe7IPD==; UserName=Smart_look; UserInfo=d43e50a1aa0c4f2caa52662c49ea3f55; UserToken=d43e50a1aa0c4f2caa52662c49ea3f55; UserNick=Amae; AU=779; BT=1635603087677; p_uid=U010000; Hm_up_6bcd52f51e9b3dce32bec4a3997715ac=%7B%22islogin%22%3A%7B%22value%22%3A%221%22%2C%22scope%22%3A1%7D%2C%22isonline%22%3A%7B%22value%22%3A%221%22%2C%22scope%22%3A1%7D%2C%22isvip%22%3A%7B%22value%22%3A%220%22%2C%22scope%22%3A1%7D%2C%22uid_%22%3A%7B%22value%22%3A%22Smart_look%22%2C%22scope%22%3A1%7D%7D; c_segment=5; dc_sid=8af578122c748c6f8f79293ff5d9c725; c_first_ref=www.baidu.com; c_first_page=https%3A//blog.csdn.net/quanqxj/article/details/89226160; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1640932419,1640958689,1641047085,1641108277; c_pref=https%3A//www.baidu.com/link; c_ref=https%3A//blog.csdn.net/Smart_look%3Fspm%3D1000.2115.3001.5343; firstDie=1; log_Id_click=32; Hm_lpvt_6bcd52f51e9b3dce32bec4a3997715ac=1641188306; log_Id_view=97; dc_session_id=10_1641198463093.943635; c_page_id=default; dc_tos=r54ku6; log_Id_pv=73",
"referer": "https://blog.csdn.net/Smart_look?spm=1000.2115.3001.5343",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
}

def get_page(page):
    params = {
        "page":page,
        'size':20,
        'businessType':'lately',
        'noMore':'false',
        'username':"Smart_look"
    }

    url = base_url + urlencode(params)
    try:
        respnose = requests.get(url,headers=headers)
        if respnose.status_code==200:
            return respnose.json()
    except requests.ConnectionError as e:
        print("Error",e.args)


if __name__ == '__main__':
    for page in range(1,5):
        json = get_page(page)
        print(json)


结果
{'code': 200, 'message': 'success', 'data': {'list': [{'type': 'blog', 'formatTime': '21 小时前', 'title': '爬虫:CSV文件存储', 'description': 'CSV,全称为 Comma-Separated Values ,中文可以叫作逗号分隔值或字符分隔值,其文件以纯文 本形式存储表格数据。该文件是一个字符序列,可以由任意数目的记录组成,记录间以某种换行符分隔,每条记录由字段组成,字段间的分隔符是其他字符或字符串,最常见的是逗号或制表符, 不过所有记录都有完全相同的字段序列 ,相当于一个结构化表的纯文本形式, 它比 Excel 文件更加简介, XLS 文本是电子表格,它包含了文本、数值、公式和格式等内容,而 CSV 中不包含这些 容,就是特定字符分割的纯文本,结', 'hasOriginal': True, 'diggCount': 0, 'commentCount': 0, 'postTime': 1641122118000, 'createTime': 1641119691000, 'url': 'https://blog.csdn.net/Smart_look/article/details/122279049', 'articleType': 1, 'viewCount': 47, 'rtype': 'article'}, {'type': 'blog', 'formatTime': '昨天', 'title': '爬虫:JSON文件存储', 'description': 'JSON ,全称为 JavaScript Object Notation 也就 JavaScript 对象标记,它通过对象和数组的组合 来表示数据,构造简洁但是结构化程度非常高,是一种轻量级的数据交换格式目录对象和数组读取Json输出JSON对象和数组JavaScript 语言中,一切都是对象, 因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、 对象 、数组等,但是对象和数组都是比较特殊且常用的两种类型,下面简要介绍一下 它们对象:他在JavaScript', 'hasOriginal': True, 'diggCount': 0, 'commentCount': 0, 'postTime': 1641109809000, 'createTime': 1641106807000, 'url': 'https://blog.csdn.net/Smart_look/article/details/122276562', 'articleType': 1, 'viewCount': 84, 'rtype': 'article'}, {'type': 'blog', 'formatTime': '昨天', 'title': '爬虫:文件存储:Text', 'description': '文件保存的形式是多种多样的,最简单的形式是直接保存文本文件,如:TEXT,JSON,CSV等,另外还可以保存到数据中,如关系型数据库Mysql,非关系型数据库等:MongoDB,Redis等TXT文本保存保存知乎上"发现"页面的"热门话题"部分,将其问题和答案统一保存成txt形式import requestsfrom pyquery import PyQuery as pqurl = "https://www.zhihu.com/explore"headers = {"user-ag', 'hasOriginal': True, 'diggCount': 0, 'commentCount': 0, 'postTime': 1641106679000, 'createTime': 1641078780000, 'url': 'https://blog.csdn.net/Smart_look/article/details/122273368', 'articleType': 1, 'viewCount': 29, 'rtype': 'article'}, {'type': 'blog', 'formatTime': '昨天', 'title': '爬虫:pyquery 解析库', 'description': '如果你比较喜欢CSS选择器,对jQuery有所了解,那么这个库更加适合——pyquery初始化向Beautiful Soup一样,初始化pyquery的时候,也需要传入HTML文本来初始化一个PyQuery对象,它的初始化方式有很多种,比如直接传入字符串,传入URL,传入文件名1、字符串初始化...', 'hasOriginal': True, 'diggCount': 0, 'commentCount': 0, 'postTime': 1641048913000, 'createTime': 1640611500000, 'url': 'https://blog.csdn.net/Smart_look/article/details/122180996', 'articleType': 1, 'viewCount': 127, 'rtype': 'article'}, {'type': 'blog', 'formatTime': '7 天前', 'title': '爬虫:Beautiful Soup', 'description': '目录Beautiful Soup 简介解释器基本用法节点选择器选择元素提起信息1、提取名称2、获取属性3、获取内容嵌套选择关联选择1、子节点和子孙节点2、父节点和祖先节点3、兄弟节点4、提取信息方法选择器1、find_all()2、find() :返回单个元素CSS选择器1、嵌套选择2、获取属性3、获取文本对于一个网页来说,都有一定的特殊结构和层级关系,而且很多节点都有 id,class 来作区分,所以借助它们.', 'hasOriginal': True, 'diggCount': 0, 'commentCount': 0, 'postTime': 1640511634000, 'createTime': 1640413116000, 'url': 'https://blog.csdn.net/Smart_look/article/details/122143056', 'articleType': 1, 'viewCount': 348, &#
  • 13
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值