python抓取动态网页(Python爬虫[动态网页数据]用法教程综述(2))
优采云 发布时间: 2022-01-28 05:10python抓取动态网页(Python爬虫[动态网页数据]用法教程综述(2))
Python爬虫4.2——ajax【动态网页数据】使用教程
概述
本系列文档用于提供Python爬虫技术学习的简单教程。在巩固你的技术知识的同时,如果你不小心对你有用,那就更好了。
Python 版本是 3.7.4
有时当我们抓取带有请求的页面时,我们得到的结果可能与我们在浏览器中看到的不同。正常显示的页面数据在浏览器中是可以看到的,但是使用requests得到的结果却不是。这是因为请求都是原创的 HTML 文档,而浏览器中的页面是通过 JavaScript 处理数据的结果。这些数据有多种来源,可以通过 Ajax 加载或收录在 HTML 中。在文档中,也可能是通过 JavaScript 和特定算法计算后生成的。
因此,如果遇到这样的页面,直接使用requests等库爬取原创页面是无法获取有效数据的。这时候就需要分析网页后端向接口发送的Ajax请求了。如果可以使用requests来模拟ajax请求,那么就可以成功抓取了。
因此,在本文中,我们主要了解Ajax是什么以及如何分析和爬取Ajax请求。
AJAX简介什么是AJAX
AJAX(异步 JavaScript 和 XML)异步 JavaScript 和 XML。通过在后台交换与服务器协商的数据,Ajax 实现了网页的异步更新,这意味着可以在不重新加载整个网页的情况下更新网页的某些部分。传统网页(不使用Ajax)如果内容需要更新,必须重新加载整个网页,因为传统的数据传输格式使用XML语法,所以称为Ajax。其实数据交互的限制基本上就是用JSON,Ajax加载的数据,即使用JS渲染数据到浏览器,查看网页源码的时候还是看不到加载的数据通过 Ajax,您只能看到 Ajax 加载的数据。由 url 加载的 HTML 代码。
示例说明
在浏览网页的时候,我们会发现很多网页已经向下滚动,可以查看更多选项。比如微博、今日头条等,有的是根据鼠标下拉自动加载的。这些其实就是Ajax加载的过程。我们可以看到页面并没有完全刷新,也就是说页面的链接没有变化,但是网页中有新的内容,也就是通过Ajax获取新数据并渲染的过程。
请求分析
使用 Chrome 开发者工具的过滤功能过滤掉所有的 Ajax 请求,这里不再详述。
也可以使用 Fiddler 数据包捕获工具进行数据包捕获分析。Fiddler工具的使用方法这里不做说明。您可以在线搜索和查看。
Ajax 响应结果一般为 json 数据格式。
获取方式直接分析Ajax使用的接口,然后通过代码请求该接口获取数据(下面的例子就是这样一个通用的)。使用 Selenium + Chromedriver 模拟浏览器行为获取数据(继续关注文章)。该方法的优点和缺点
分析界面
可以直接请求数据,不需要做一些解析工作,代码量小,性能高。
解析接口比较复杂,尤其是一些被js搞糊涂的接口,必须对js有一定的了解,很容易被爬虫发现。
硒
直接模拟浏览器的行为,浏览器能请求的也可以用selenium来请求,爬虫更稳定。
大量代码和低性能。
示例说明
让我们举个例子,爬取“长得好看的程序员是怎样一种体验”这个问题的所有答案。在问题 知乎 下。示例代码如下:
<p># 引入所需库
import json
import requests
# 声明定义请求头
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) '
'AppleWebKit/537.36 (KHTML, '
'like Gecko) Chrome/67.0.3396.99 '
'Safari/537.36',
'Host': "www.zhihu.com",
'Referer': "https://www.zhihu.com/question/37787176"
}
def answer(url_):
"""
获取问题答案
:param url_:
:return:
"""
r = requests.get(url_, headers=header)
data = r.text
jsonobj = json.loads(data)
return jsonobj
# 问题答案接口地址
url = "https://www.zhihu.com/api/v4/questions/37787176/answers?include=data%5B%2A%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_labeled%2Cis_recognized%2Cpaid_info%3Bdata%5B%2A%5D.mark_infos%5B%2A%5D.url%3Bdata%5B%2A%5D.author.follower_count%2Cbadge%5B%2A%5D.topics&limit=5&offset=0&platform=desktop&sort_by=default"
# 获取回答总数
answer_total = int(answer(url)['paging']['totals'])
offset = 0
while offset