动态网页数据抓取方法详解
来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习文章相关编程知识。下面本篇文章就来带大家聊聊《动态网页数据抓取技巧解析》,介绍一下,希望对大家的知识积累有所帮助,助力实战开发!
1. 传统网页抓取面临的挑战
在进行网页数据抓取时,我们经常会遇到内容并非一次性加载完成的网站。许多现代网站为了提升用户体验,会采用JavaScript动态加载数据,例如“加载更多”、“无限滚动”或通过点击按钮显示隐藏内容等。在这种情况下,仅仅使用requests库获取初始HTML内容,并结合BeautifulSoup进行解析,往往只能获取到页面首次加载时可见的部分数据。
例如,对于一个包含大量数据列表的页面,如 https://www.racingpost.com/bloodstock/sales/catalogues/5/2023-12-04,初次加载时可能只显示前50条记录。页面底部通常会有一个“加载更多”的按钮或提示,点击后才会通过异步请求加载后续数据。此时,如果直接解析初始HTML,你将无法获取到这些隐藏的数据。
from bs4 import BeautifulSoup as BS import requests import re url = 'https://www.racingpost.com/bloodstock/sales/catalogues/5/2023-12-04' res = requests.get(url) print(f"HTTP Status Code: {res.status_code}") soup = BS(res.content, "html.parser") # 尝试从初始HTML中提取数据,可能只获得部分内容 # string = str(soup.find_all("script", type="text/javascript")[1]) # raw_data = re.findall(r'\{"lot(.*?)\}', string) # print(f"通过初始HTML解析到的数据条数: {len(raw_data)}") # 此时,len(raw_data)通常远小于页面实际的总数据量
上述代码尝试从初始HTML中提取数据,但由于数据是动态加载的,这种方法无法获取到所有分页内容。
2. 识别并利用隐藏的数据API
解决动态加载数据问题的关键在于,理解这些“隐藏”的数据并非真的隐藏,而是通过JavaScript向服务器发送了额外的请求来获取。这些请求通常会指向一个专门的数据接口(API),其返回格式多为JSON或XML。通过直接调用这些API,我们可以绕过前端渲染过程,直接获取原始数据,从而实现更高效、更稳定的数据抓取。
如何识别API接口?
最常用的方法是使用浏览器的开发者工具(通常按F12键打开)。
- 打开目标网页。
- 切换到“网络”(Network)或“XHR/Fetch”选项卡。
- 刷新页面,或点击页面上的“加载更多”按钮。
- 观察网络请求列表,寻找那些返回JSON或XML格式数据的请求。这些请求的URL通常包含“api”、“data”、“json”等关键词,并且请求参数(如page、offset、limit)会指示分页信息。
对于本案例中的 racingpost.com 页面,经过观察,可以发现其数据实际上是从 https://www.racingpost.com/bloodstock/sales/catalogues/5/2023-12-04/data.json 这个JSON接口获取的。这个接口不仅提供了数据,还包含了分页元数据,如总页数。
3. 通过API接口抓取完整数据
一旦确定了数据API接口,我们就可以直接使用requests库来请求这些接口,获取完整的JSON数据。
import requests import json # 导入json库以便更好地处理数据 # 定义基础URL和数据API路径 base_url = 'https://www.racingpost.com/bloodstock/sales/catalogues/5/2023-12-04' data_api_url = f'{base_url}/data.json' # 1. 获取分页元数据 try: page_metadata_response = requests.get(data_api_url) page_metadata_response.raise_for_status() # 检查HTTP请求是否成功 page_metadata = page_metadata_response.json() # 提取总页数 total_pages = page_metadata['pagination']['totalPages'] print(f"发现总页数: {total_pages}") all_data = [] # 用于存储所有页的数据 # 2. 遍历所有页,抓取数据 for page in range(1, total_pages + 1): print(f"正在抓取第 {page}/{total_pages} 页数据...") # 发送带分页参数的请求 response = requests.get(data_api_url, params={'page': str(page)}) response.raise_for_status() # 检查HTTP请求是否成功 # 解析JSON响应,提取'rows'字段的数据 page_data = response.json()['rows'] all_data.extend(page_data) # 将当前页数据添加到总列表中 # 可以在此处添加延迟,防止请求过快被封禁 # import time # time.sleep(0.5) print(f"\n成功抓取到总计 {len(all_data)} 条数据。") # 打印前几条数据作为示例 if all_data: print("部分抓取到的数据示例:") for i, item in enumerate(all_data[:5]): # 打印前5条 print(f" 数据 {i+1}: {item}") # 可以将数据保存到文件 # with open('racingpost_data.json', 'w', encoding='utf-8') as f: # json.dump(all_data, f, ensure_ascii=False, indent=4) # print("数据已保存到 racingpost_data.json") except requests.exceptions.RequestException as e: print(f"请求发生错误: {e}") except KeyError as e: print(f"JSON解析错误,键不存在: {e}. 响应内容可能不符合预期。") print(f"原始响应内容: {page_metadata_response.text if 'page_metadata_response' in locals() else response.text}") except json.JSONDecodeError as e: print(f"JSON解码错误: {e}. 响应内容可能不是有效的JSON。") print(f"原始响应内容: {page_metadata_response.text if 'page_metadata_response' in locals() else response.text}")
代码解析:
- 确定API URL: 根据开发者工具的发现,我们构建了 data_api_url。
- 获取元数据: 首先向 data.json 发送一个请求,获取包含 pagination 信息的JSON。从 pagination['totalPages'] 中提取总页数。
- 循环抓取: 使用一个 for 循环,从第1页迭代到 total_pages。
- 传递分页参数: 在每次循环中,通过 params={'page': str(page)} 将当前页码作为查询参数传递给API。这是API识别并返回对应页数据的方式。
- 解析JSON: response.json() 方法将HTTP响应体解析为Python字典或列表。本例中,实际数据位于返回JSON的 rows 键下。
- 数据汇总: 将每页获取到的数据列表通过 extend() 方法添加到 all_data 总列表中。
- 错误处理: 增加了 try-except 块来捕获 requests 库可能抛出的网络错误 (RequestException)、JSON解析错误 (JSONDecodeError) 或字典键不存在错误 (KeyError),增强了代码的健壮性。
4. 优势与注意事项
通过API抓取数据的优势:
- 高效: 无需解析复杂的HTML结构,直接获取结构化数据,解析速度更快。
- 稳定: API接口通常比HTML结构稳定,网站前端改版对API的影响较小。
- 完整性: 能够获取到所有动态加载的数据,解决了传统方法无法获取完整数据的痛点。
- 资源消耗低: 不需要渲染页面,节省了CPU和内存资源。
注意事项:
- API文档: 如果有API文档,务必查阅,了解参数、返回格式和限制。
- 请求频率: 大多数网站对API请求有频率限制(Rate Limiting)。过于频繁的请求可能导致IP被封禁。建议在每次请求之间添加 time.sleep() 延迟。
- User-Agent: 在某些情况下,服务器会检查请求的 User-Agent 头。模拟浏览器行为可以提高成功率。
- 错误处理: 务必添加健壮的错误处理机制,例如网络中断、API返回非预期数据格式等情况。
- 遵守Robots.txt和网站政策: 在进行任何抓取活动前,请务必查看网站的 robots.txt 文件,并遵守其使用条款和隐私政策。尊重网站的数据所有权和服务器负载。
总结
当面对动态加载内容的网页时,仅仅依赖于初始HTML和BeautifulSoup进行解析往往是不足的。通过使用浏览器的开发者工具,识别并直接访问网页背后的数据API接口,是获取完整、结构化数据的更高效、更稳定的方法。这种方法不仅简化了数据解析过程,也大大提高了数据抓取的成功率和效率。掌握这一技巧,将使你在复杂的网页数据抓取任务中游刃有余。
今天关于《动态网页数据抓取方法详解》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

- 上一篇
- VisionStory3D效果制作全攻略

- 下一篇
- C盘变红怎么清理?三招轻松解决
-
- 文章 · python教程 | 10分钟前 |
- Python中id的作用与对象识别解析
- 138浏览 收藏
-
- 文章 · python教程 | 14分钟前 |
- Python多列排序技巧:sort_values实用教程
- 406浏览 收藏
-
- 文章 · python教程 | 22分钟前 |
- Python中ans是什么意思及使用场景
- 344浏览 收藏
-
- 文章 · python教程 | 38分钟前 |
- Python图像处理性能优化与并发实战
- 476浏览 收藏
-
- 文章 · python教程 | 40分钟前 |
- Python自动化办公:pyautogui实战教程
- 371浏览 收藏
-
- 文章 · python教程 | 50分钟前 |
- YOLOv8图像尺寸适配解析与应用
- 392浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python操作Redis事务详解
- 141浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- PythonGUI自动化教程:PyAutoGUI使用详解
- 459浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- PythonPyqt5开发教程:桌面应用入门指南
- 146浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python计算百分比的实用方法
- 249浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 千音漫语
- 千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
- 113次使用
-
- MiniWork
- MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
- 109次使用
-
- NoCode
- NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
- 126次使用
-
- 达医智影
- 达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
- 118次使用
-
- 智慧芽Eureka
- 智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
- 122次使用
-
- Flask框架安装技巧:让你的开发更高效
- 2024-01-03 501浏览
-
- Django框架中的并发处理技巧
- 2024-01-22 501浏览
-
- 提升Python包下载速度的方法——正确配置pip的国内源
- 2024-01-17 501浏览
-
- Python与C++:哪个编程语言更适合初学者?
- 2024-03-25 501浏览
-
- 品牌建设技巧
- 2024-04-06 501浏览