解决动态加载内容爬取问题:利用XHR请求获取隐藏数据

解决动态加载内容爬取问题:利用XHR请求获取隐藏数据

本教程旨在解决使用beautifulsoup爬取网页时,因内容动态加载而无法获取目标数据的问题。当页面元素通过javascript的xhr请求异步加载时,直接解析初始html将失败。文章将详细阐述如何通过浏览器开发者工具识别这些xhr请求,并利用python的`requests`库直接调用api接口,从而成功获取并处理动态生成的数据。

在进行网页数据抓取时,开发者常会遇到一个常见问题:尽管在浏览器中能看到完整的页面内容,但使用BeautifulSoup等解析工具获取到的HTML却缺少部分目标数据。这通常是由于网站采用了动态加载技术,即页面内容并非一次性从服务器加载,而是通过JavaScript在页面加载完成,通过XMLHttpRequest (XHR) 或 Fetch API 异步请求数据并更新DOM。

理解动态加载与XHR请求

当您尝试从https://www.parliament.lk/en/members-of-parliament/directory-of-members/?cletter=A这样的页面抓取

标签下的内容,但soup.find(‘ul’, id=’demoFour’)返回空标签时,这正是动态加载的典型表现。页面上的成员列表很可能是在初始HTML加载完毕后,通过JavaScript向后端发送了一个API请求,然后将返回的数据渲染到id=”demoFour”的中。

要解决这个问题,关键在于识别并模拟这些幕后的XHR请求。您可以使用浏览器的开发者工具(通常按F12打开)来检查这些请求:

打开目标网页。打开开发者工具,切换到“网络 (Network)”标签页。刷新页面,或者在页面上进行任何可能触发数据加载的操作(例如点击分页、筛选等)。在“网络”标签页中,筛选“XHR”或“Fetch/XHR”类型,观察是否有请求返回了您想要的数据。通常这些请求的URL会包含api、data或与页面内容相关的关键词,并且响应类型多为JSON。

通过分析,我们可以发现,该网站的成员列表数据实际上是通过向https://www.parliament.lk/members-of-parliament/directory-of-members/index2.php发送一个POST请求获取的,该请求的参数包括了字母筛选(letter)等信息,并返回JSON格式的数据。

解决方案:直接调用API接口

一旦确定了数据源的API接口,我们就可以绕过前端渲染过程,直接使用Python的requests库向该接口发送请求,获取原始数据。

以下是实现这一策略的Python代码示例:

from bs4 import BeautifulSoupimport requestsimport stringimport json # 导入json库用于处理JSON响应# 存储抓取到的数据data = []# 遍历所有大写字母,模拟页面按字母筛选的功能for letter in list(string.ascii_uppercase):    # 构建API请求URL和POST请求体    api_url = 'https://www.parliament.lk/members-of-parliament/directory-of-members/index2.php'    # 注意:这里是一个POST请求,需要传递form data    payload = {        'option': 'com_members',        'task': 'all',        'tmpl': 'component',        'letter': letter,        'wordfilter': '',        'search_district': ''    }    try:        # 发送POST请求获取数据        # 实际的请求是POST,并且参数在请求体中        result = requests.post(api_url, data=payload)        result.raise_for_status() # 检查HTTP请求是否成功 (状态码200)        # 解析JSON响应        members_json = result.json()        # 遍历返回的成员列表        for member_info in members_json:            # 提取所需信息并添加到数据列表中            data.append({                'url': f"https://www.parliament.lk/en/members-of-parliament/directory-of-members/viewMember/{member_info['mem_intranet_id']}",                'id': member_info['mem_intranet_id'],                'name': member_info['member_sname_eng']            })    except requests.exceptions.RequestException as e:        print(f"请求字母 '{letter}' 时发生错误: {e}")    except json.JSONDecodeError as e:        print(f"解析字母 '{letter}' 的响应时发生JSON错误: {e}")# 打印抓取到的数据print(data)

代码解析:

导入必要的库:requests用于发送HTTP请求,string用于生成字母列表,json用于解析API返回的JSON数据。遍历字母表:网站的成员目录是按字母分类的,因此我们通过遍历string.ascii_uppercase来模拟按字母筛选的操作,确保获取所有成员的信息。构建API请求:api_url是实际提供成员数据的后端接口地址。payload是一个字典,包含了POST请求所需的表单数据(form data),这些参数是从开发者工具中分析XHR请求的“负载 (Payload)”或“表单数据 (Form Data)”部分获取的。发送POST请求:使用requests.post()方法发送POST请求,并将payload作为data参数传递。错误处理:result.raise_for_status()用于在HTTP请求返回错误状态码时抛出异常。try-except块用于捕获网络请求和JSON解析可能发生的错误,提高程序的健壮性。解析JSON响应:result.json()方法将HTTP响应体解析为Python字典或列表。提取并存储数据:遍历解析后的JSON数据,提取每个成员的ID、英文名等信息,并构建一个包含成员详情URL的字典,最后将其添加到data列表中。

抓取结果示例

执行上述代码后,data列表将包含一个结构化的字典列表,每个字典代表一个议会成员,包含其URL、ID和姓名,例如:

[{'url': 'https://www.parliament.lk/en/members-of-parliament/directory-of-members/viewMember/3266',  'id': '3266',  'name': 'A. Aravindh Kumar'}, {'url': 'https://www.parliament.lk/en/members-of-parliament/directory-of-members/viewMember/50',  'id': '50',  'name': 'Abdul Haleem'}, {'url': 'https://www.parliament.lk/en/members-of-parliament/directory-of-members/viewMember/3325',  'id': '3325',  'name': 'Ajith Rajapakse'}, ...]

注意事项与进阶

User-Agent和Headers:某些网站可能会检查请求头中的User-Agent。如果直接请求API被拒绝,尝试在requests.post()中添加headers参数,模拟浏览器行为。频率限制与IP封锁:频繁的请求可能会触发网站的频率限制或IP封锁。考虑添加time.sleep()在请求之间设置延迟,或使用代理IP池。动态参数:本例中的letter参数是显而易见的。在更复杂的场景中,API请求的参数可能包含动态生成的令牌(token)、时间戳或其他加密信息。这需要更深入的分析JavaScript代码来理解其生成逻辑。详细页面抓取:本教程只获取了成员的基本信息。如果需要每个成员的详细资料,您可以使用抓取到的url字段,进一步对每个成员的详情页发送requests.get()请求,并使用BeautifulSoup解析这些详情页。

总结

当传统的BeautifulSoup解析方法无法获取到网页上的内容时,很可能是因为内容通过JavaScript动态加载。解决之道在于利用浏览器开发者工具分析网络请求,找到数据源的API接口,并直接使用requests库模拟这些XHR请求来获取原始数据。这种方法更直接、高效,并且能获取到结构化的JSON数据,极大地简化了数据处理过程。掌握这一技巧,将使您在面对现代动态网页时,能够更有效地进行数据抓取。

以上就是解决动态加载内容爬取问题:利用XHR请求获取隐藏数据的详细内容,更多请关注php中文网其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1598912.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
Python实现文本文件行号自动递增写入教程
上一篇 2026年5月10日 10:41:38
Python网页版如何实现邮件发送_Python网页版邮件自动发送功能开发教程
下一篇 2026年5月10日 10:41:44

相关推荐

  • C++开发环境配置Visual Studio的完整流程

    配置C++开发环境需先安装Visual Studio并勾选“使用C++的桌面开发”工作负载,它包含MSVC编译器、Windows SDK、标准库和项目模板等核心组件。创建项目后可编写代码并运行调试。集成第三方库时,头文件-only库只需配置“附加包含目录”;静态库或动态库还需设置“附加库目录”和“附…

    2026年5月10日
    000
  • 如何在Div中垂直排版文本(从下到上)

    本文详细介绍了在网页设计中实现文本从底部到顶部垂直排版的两种主要css技术。首先,探讨了利用`transform`属性进行精确旋转和定位的方法,包括`rotate(-90deg)`和`translatex(-100%)`的组合应用。其次,介绍了结合`writing-mode: vertical-rl…

    2026年5月10日
    000
  • 前端数据属性搜索指南:实现精确匹配与模糊查询

    本文详细介绍了如何在前端开发中,特别是使用jQuery时,对HTML元素的data属性进行有效搜索。教程涵盖了两种主要方法:一是利用jQuery选择器实现data属性的精确匹配查找;二是引入第三方库Fuse.js,实现更灵活、支持部分匹配和容错的模糊搜索功能,并提供了详细的代码示例和实现步骤,帮助开…

    2026年5月10日
    100
  • Discord用户头像链接的动态获取与管理:技术限制解析

    本文探讨了获取discord用户头像持久且自动更新链接的可能性。结论是,由于discord为每次上传的图片生成随机url,直接获取一个“永不失效”的静态链接是不可能的。若需在网页上展示动态更新的头像,开发者必须通过编程方式,利用discord api实时获取用户的最新头像url。 Discord头像…

    2026年5月10日
    000
  • Laravel中基于用户认证状态与用户角色安全地控制UI元素显示

    本文详细介绍了在Laravel应用中,如何根据用户的认证状态(访客或已登录)以及已登录用户的特定角色,安全且高效地控制前端UI元素的显示与隐藏。文章将重点解决直接访问`auth()->user()`可能导致的空指针错误,并提供一个健壮的条件判断解决方案,确保无论用户是否登录,应用都能正常运行并…

    2026年5月10日
    100
  • js如何删除数组指定元素 数组元素删除的3种高效方法

    js如何删除数组指定元素 数组元素删除的3种高效方法js如何删除数组指定元素 数组元素删除的3种高效方法js如何删除数组指定元素 数组元素删除的3种高效方法js如何删除数组指定元素 数组元素删除的3种高效方法

    删除javascript数组中的指定元素有三种常用方法。1. 使用splice()直接修改原数组,适合删除单个元素但需注意副作用;2. 使用filter()创建新数组,保留原数组且可删除多个匹配元素;3. 结合findindex()和splice(),适用于根据对象属性删除元素。选择方法需考虑是否修…

    2026年5月10日 用户投稿
    000
  • HTML弹窗怎么设置_SEO友好的弹窗实现方案

    答案:SEO友好的HTML弹窗需将内容预置于DOM中,通过CSS隐藏,再用JavaScript控制显示与隐藏,确保搜索引擎可抓取且不影响用户体验。 HTML弹窗的设置,核心在于通过HTML结构、CSS样式和JavaScript交互来实现内容的动态显示与隐藏。要让弹窗对SEO友好,我们得从内容的可抓取…

    2026年5月10日
    000
  • CSS中背景图片与背景色的叠加及定位技巧

    本文深入探讨了在css中如何有效地将背景图片与背景颜色结合使用,并精确控制图片位置。文章首先介绍了background-image和background-color的基本层叠原理及定位属性,随后分析了背景图片不生效或定位异常的常见原因,特别是css优先级冲突。针对此问题,提供了使用!importan…

    2026年5月10日
    000
  • c++ socket编程入门 c++网络通信代码实例

    核心是使用socket API实现TCP通信,服务端依次创建套接字、绑定、监听、接受连接并收发数据,客户端则连接后发送消息并接收响应,需注意跨平台差异与错误处理。 想快速上手 C++ Socket 编程?其实核心就是使用操作系统提供的 socket API,通过创建套接字、绑定地址、监听连接(服务端…

    2026年5月10日
    000
  • Python网页版如何实现邮件发送_Python网页版邮件自动发送功能开发教程

    使用Flask和Flask-Mail可实现网页邮件发送功能,需配置SMTP服务(如QQ邮箱)、创建表单并处理发送逻辑,注意安全措施如环境变量管理密码、输入校验及异步发送优化。 在Python网页应用中实现邮件发送功能,是许多项目(如用户注册验证、密码重置、通知提醒等)的常见需求。本文将介绍如何使用F…

    2026年5月10日
    000
  • Python实现文本文件行号自动递增写入教程

    本教程详细介绍了如何使用python向文本文件追加数据时,自动为每行添加一个格式化的递增序列号。通过巧妙利用文件读写模式和文件指针定位,我们能够准确获取现有行数,并生成如”001″、”002″等格式的序列号,确保每次写入的数据都带有正确的行号。 Pyt…

    2026年5月10日
    000
  • 输出格式要求:项目文件夹重命名是否会破坏Python中的虚拟环境?

    项目文件夹重命名后,虚拟环境可能会失效。这是因为虚拟环境中的一些文件包含了硬编码的路径,指向原始的项目文件夹。重命名后,这些路径不再正确,导致虚拟环境无法正常激活和使用,从而影响项目依赖的管理和运行。 虚拟环境(venv)是Python中用于隔离项目依赖的常用工具。它通过创建一个独立的目录,并在其中…

    2026年5月10日
    000
  • 构建可直接链接的动态标签页:HTML、CSS与JavaScript实践指南

    本教程详细阐述了如何在Web页面中创建可直接链接到特定标签页内容的导航系统。通过结合HTML锚点、CSS样式和JavaScript动态逻辑,文章提供了一种优化方案,实现了按需加载、高效显示标签页内容,并确保了从外部URL直接访问特定标签页的功能。内容涵盖了从基础的JavaScript控制到更高级的动…

    2026年5月10日
    000
  • 在树莓派上正确安装和配置Tesseract-OCR

    本文提供在树莓派上正确安装和配置Tesseract-OCR的详细教程。针对用户常遇到的因错误使用Windows二进制文件或Wine导致FileNotFoundError的问题,本教程将重点介绍如何利用Debian/Raspberry Pi OS原生软件包进行安装,并指导PyTesseract的正确路…

    2026年5月10日
    100
  • Python教程:从字符串中高效提取数值列表的最大值与最小值

    本教程将指导您如何在python中处理一个包含空格分隔数字的字符串,并从中高效地找出最大值和最小值。我们将探讨字符串拆分、类型转换、以及使用排序或内置函数来定位极端值的方法,最终将结果格式化为指定字符串输出。文章将提供详细的代码示例和注意事项,帮助您构建健壮的解决方案。 在日常编程中,我们经常会遇到…

    2026年5月10日
    300
  • python切片如何进行索引

    Python切片通过start:stop:step提取序列部分,遵循左闭右开原则,正向索引从0开始,反向从-1开始,省略参数取默认值,步长控制方向与间隔,不改变原序列且越界不报错。 Python切片通过指定起始、结束和步长来提取序列的一部分,使用方括号内的冒号分隔索引。基本语法是 sequence[…

    2026年5月10日
    000
  • 解决 Pyheif 安装失败:理解并安装 libheif 核心依赖

    Pyheif库在Python项目中用于处理HEIC/HEIF图像格式,但其安装常因缺少底层的C语言库libheif而失败。本文详细阐述了Pyheif与libheif的依赖关系,并提供了在macOS、Linux和Windows系统上安装libheif的具体步骤,从而解决Pyheif安装时常见的编译错误…

    2026年5月10日
    000
  • Laravel数据库用户计数与列表显示教程

    本教程详细介绍了如何在laravel应用中正确地从数据库获取用户总数和用户列表,并将其显示在视图中。我们将区分`count()`和`get()`方法的用法及其返回类型,展示控制器与视图代码的正确搭配,帮助开发者避免常见错误,实现精确的数据展示,确保数据处理逻辑与前端渲染需求一致。 在Laravel应…

    2026年5月10日
    000
  • Node.js脚本输出实践:理解console.log与数组操作

    本教程旨在解决node.js脚本运行时无输出的问题。核心在于理解node.js不会自动打印函数定义或变量赋值的结果,必须通过`console.log()`显式输出。我们将演示如何使用`array.prototype.map()`高效处理数组,并通过`array.prototype.join()`格式…

    2026年5月10日
    000
  • Golang反射安全吗 讨论Golang反射的安全性问题

    Golang反射安全吗 讨论Golang反射的安全性问题Golang反射安全吗 讨论Golang反射的安全性问题Golang反射安全吗 讨论Golang反射的安全性问题Golang反射安全吗 讨论Golang反射的安全性问题

    golang的反射机制在灵活性与安全性之间需要权衡,其安全性取决于使用方式。反射可能破坏类型安全,如通过reflect.valueof()和set()修改私有字段,导致类型错误和封装性破坏;同时带来性能开销,频繁调用反射方法会增加gc压力,影响高并发性能。为安全使用反射,应避免不必要的使用,优先考虑…

    2026年5月10日 用户投稿
    000

发表回复

登录后才能评论
关注微信