爬取【ajax+json】异步加载的网站
2018-02-04 10:02
281 查看
@导入类库
@请求地址和请求头
@发起请求,并获得html文档的页面元素树
@解析首页信息
@点击首页底部的分页页码时,地址栏不会发生变化,由此我们知道该网站的分页信息是通过ajax做异步加载的
@知道了分页数据的加载地址之后,我们逐页发起请求,获取其json数据,并做分析和提取
@爬取效果
@完整代码
import requests from lxml import etree import json import time
@请求地址和请求头
# 请求头,用于伪装客户端浏览器,可由抓包获取 header_base = { 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36', 'Upgrade-Insecure-Requests': '1', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9', } # 首页 URL url_str = 'https://www.douyu.com/directory/all'
@发起请求,并获得html文档的页面元素树
# 获取首页信息 response = requests.get(url=url_str, headers=header_base) # print(response.text) # print(response.status_code) # 获得页面的元素树 html = etree.HTML(response.text)
@解析首页信息
# 通过xpath提取房间信息:播主和在线人数 info_list = html.xpath( "//ul[@id='live-list-contentbox']//span[@class='dy-name ellipsis fl']/text() \ | //ul[@id='live-list-contentbox']//span[@class='dy-num fr']/text()" ) # 播主昵称 host_names = info_list[0] print('first_name : ', host_names) # 打印所有房间信息 for info in info_list: print(info)
@点击首页底部的分页页码时,地址栏不会发生变化,由此我们知道该网站的分页信息是通过ajax做异步加载的
# 这里我们发现当点击第二页时,浏览器的地址栏并没有发生变化 # 无法直接从页面获取页码,因为页码是通过JS生成的 # page_num = html.xpath("//a[@class='shark-pager-item']/text()") # print('page_num : ', page_num)
@知道了分页数据的加载地址之后,我们逐页发起请求,获取其json数据,并做分析和提取
# 该网站的分页数据是通过ajax异步加载的(无法直接从浏览器的地址栏获取其页面的URL) # 需要借助抓包工具或页面控制台获得ajax异步请求所发送请求的url page = 1 while True: # 不断爬取下一页 page += 1 # 通过抓包分析获得的分页地址 url_str = 'https://www.douyu.com/gapi/rkc/directory/0_0/' + str(page) print(url_str) # 请求房间信息 response = requests.get(url=url_str, headers=header_base) # print(response.text) # 从第二页开始,数据以json格式加载,因此先将文本转换为json info_json = json.loads(response.text) # print(type(info_json['data']['rl'])) # 当请求的页码大于最大页码时返回的是第一页数据 # 我们以此作为循环退出条件 print('========', info_json['data']['rl'][0]['nn'],"==========") if host_names == info_json['data']['rl'][0]['nn']: break # 分析json信息,循环获取每个直播房间的信息 for one_info in info_json['data']['rl']: # 获取主播名称 host = one_info['nn'] # 获取直播在看人数 onlines = one_info['ol'] # 睡一会再接着爬下一页,以免请求过于频繁被反爬 time.sleep(2)
@爬取效果
@完整代码
import requests from lxml import etree import json import time
# 请求头,用于伪装客户端浏览器,可由抓包获取 header_base = { 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36', 'Upgrade-Insecure-Requests': '1', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9', } # 首页 URL url_str = 'https://www.douyu.com/directory/all'
# 获取首页信息 response = requests.get(url=url_str, headers=header_base) # print(response.text) # print(response.status_code) # 获得页面的元素树 html = etree.HTML(response.text)
# 通过xpath提取房间信息:播主和在线人数 info_list = html.xpath( "//ul[@id='live-list-contentbox']//span[@class='dy-name ellipsis fl']/text() \ | //ul[@id='live-list-contentbox']//span[@class='dy-num fr']/text()" ) # 播主昵称 host_names = info_list[0] print('first_name : ', host_names) # 打印所有房间信息 for info in info_list: print(info)
# 这里我们发现当点击第二页时,浏览器的地址栏并没有发生变化 # 无法直接从页面获取页码,因为页码是通过JS生成的 # page_num = html.xpath("//a[@class='shark-pager-item']/text()") # print('page_num : ', page_num)
# 该网站的分页数据是通过ajax异步加载的(无法直接从浏览器的地址栏获取其页面的URL)
# 需要借助抓包工具或页面控制台获得ajax异步请求所发送请求的url
page = 1
while True:
# 不断爬取下一页
page += 30
# 通过抓包分析获得的分页地址
url_str = 'https://www.douyu.com/gapi/rkc/directory/0_0/' + str(page)
print(url_str)
# 请求房间信息
response = requests.get(url=url_str, headers=header_base)
# print(response.text)
# 从第二页开始,数据以json格式加载,因此先将文本转换为json
info_json = json.loads(response.text)
# print(type(info_json['data']['rl']))
# 当请求的页码大于最大页码时返回的是第一页数据
# 我们以此作为循环退出条件
print('========', info_json['data']['rl'][0]['nn'],"==========")
if host_names == info_json['data']['rl'][0]['nn']:
break
# 分析json信息,循环获取每个直播房间的信息
for one_info in info_json['data']['rl']:
# 获取主播名称
host = one_info['nn']
# 获取直播在看人数
onlines = one_info['ol']
# 睡一会再接着爬下一页,以免请求过于频繁被反爬
time.sleep(2)
print('OVER !!!')
相关文章推荐
- ajax异步加载解析复杂json(集合中包含对象,对象中包含对象)数据
- 从网站解析JSON异步加载到ListView事例
- 通过ajax和json进行表单验证(异步加载)
- 关于jquery+ajax+json+ssh框架整合,数值异步的问题(暂时解决方案--延迟加载(lazy)改为急加载)
- input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has
- 使用Ajax异步加载请求JSON数据
- ajax异步加载的小问题
- 原生js实现ajax异步加载
- Symfony2.x EasyUI Ajax 异步加载DataGrid 分页
- ajax异步加载回跳定位
- flask+sqlite3+echarts3+ajax 异步数据加载
- ajax异步传输json格式的例子
- JQuery 异步处理,ajax post get getJSON...
- 使用getJSON()方法异步加载JSON格式数据
- 做了MVC模式一年,可不要把传统模式忘记呀!ashx配合aspx实现AJAX加载JSON数据
- 【Android学习笔记系列】AsyncTask、BaseAdapter整合异步加载用例(通过解析JSON格式数据加载网络图片内容)
- Ajax异步从后台取Json数据
- android通过json解析到的路径后异步加载网络图片
- 异步加载(AsyncTask异步任务、Handler、Json解析、Lrucache缓存、ListView滑动优化等来实现ListView图文混排)
- 在线课堂:采用AJAX实现网站异步交互过程