讲师中心 微信公众号
AI工具推荐 视频效率加速

Python爬取动态加载内容的隐藏电话号码:API请求方法详解

大瑶姑娘_8736

大瑶姑娘_8736

发布时间:2025-11-13 13:23:04

|

969人浏览过

|

来源于php中文网

原创

Python爬取动态加载内容的隐藏电话号码:API请求方法详解

本教程旨在解决使用beautifulsoup无法直接爬取动态加载内容中隐藏电话号码的问题。当目标网站通过javascript异步请求(如graphql api)动态更新dom时,传统的html解析器将失效。文章详细介绍了如何利用浏览器开发者工具分析网络请求,识别数据源api,并使用python的`requests`库模拟这些api请求,从而高效准确地获取所需数据。

在现代网页中,许多内容并非直接嵌入在初始HTML文档中,而是通过JavaScript在用户交互(例如点击按钮)后异步加载。对于这类动态内容,仅依赖于BeautifulSoup这样的静态HTML解析库是不足以获取到完整信息的。本文将以从弹出按钮中抓取隐藏电话号码为例,详细讲解如何通过模拟API请求来解决这一挑战。

1. 理解动态内容加载的挑战

当你尝试使用requests库获取网页内容并用BeautifulSoup解析时,如果目标数据(如电话号码)只有在点击某个按钮后才显示,那么你获取到的HTML将不包含这些数据。这是因为BeautifulSoup只能处理服务器返回的原始HTML。而按钮点击后触发的数据加载通常是通过浏览器执行JavaScript代码,向后端API发送请求,然后将返回的数据动态插入到网页DOM中。

在我们的例子中,点击“التواصل”按钮后弹出的电话号码,就是通过JavaScript向一个GraphQL API发送POST请求获取的。

2. 利用浏览器开发者工具分析网络请求

要获取动态加载的数据,我们首先需要找出是哪个API提供了这些数据。浏览器开发者工具(通常按F12键打开)的“网络”(Network)选项卡是关键。

立即学习“Python免费学习笔记(深入)”;

  1. 打开目标网页: 访问你想要爬取的页面,例如 https://haraj.com.sa/1194697687。
  2. 打开开发者工具: 在浏览器中按F12,切换到“网络”(Network)选项卡。
  3. 筛选XHR/Fetch请求: 在网络面板中,通常会有筛选器,选择“XHR”或“Fetch/XHR”,这样可以只显示JavaScript发起的异步请求。
  4. 触发数据加载: 点击网页上的“التواصل”按钮。
  5. 识别API请求: 在网络面板中观察新出现的请求。通常,你会看到一个POST请求,其URL可能包含“graphql”或“api”等字样。点击该请求,查看其详细信息:
    • URL: 请求的目标地址(例如 https://graphql.haraj.com.sa)。
    • 请求方法: 通常是POST。
    • 请求头(Request Headers): 包含User-Agent等信息。
    • 请求载荷(Request Payload): 这是最重要的部分,它包含了发送给API的数据,通常是JSON格式。对于GraphQL,你会看到query和variables等字段。
    • 响应(Response): API返回的数据,通常也是JSON格式,其中包含我们所需的电话号码。

通过分析,我们可以发现当点击按钮时,浏览器向 https://graphql.haraj.com.sa 发送了一个POST请求,请求载荷中包含一个GraphQL查询,以及一个postId变量。

Windows 日历同步
Windows 日历同步

将提醒同步至 Windows/Outlook 日历。用户提及「提醒我」「设置提醒」「加到日历」「同步到日历」「日程」「calendar」「日历」时触发。支持Microsoft Graph API 设备代码流认证,无需 Web 服务器,直接写入用户 Outlook 日历。

下载

3. 提取关键参数:postId

在分析请求载荷时,我们注意到一个名为postId的变量是动态的。这个postId通常可以从原始网页的URL中提取。例如,如果页面URL是 https://haraj.com.sa/1194697687,那么postId可能就是URL末尾的数字部分,但可能需要去除某些前缀。

根据观察,URL中的1194697687对应的postId是94697687,这意味着需要去除前两位数字11。

以下是一个提取postId的示例函数:

import re

def extract_post_id_from_url(url):
    """
    从Haraj网站的URL中提取postId。
    示例: "https://haraj.com.sa/1194697687" -> 94697687
    """
    match = re.search(r'/(\d+)$', url)
    if match:
        full_id_str = match.group(1)
        # 根据观察,postId是URL末尾数字去除前两位"11"后的部分
        if full_id_str.startswith('11') and len(full_id_str) > 2:
            return int(full_id_str[2:])
        return int(full_id_str) # 如果没有"11"前缀,则直接返回
    return None

# 示例用法
target_url = "https://haraj.com.sa/1194697687"
post_id = extract_post_id_from_url(target_url)
if post_id:
    print(f"提取到的 Post ID: {post_id}")
else:
    print("无法从URL中提取 Post ID。")

4. 模拟API请求获取数据

一旦我们识别了API请求的URL、方法、头部和载荷,就可以使用Python的requests库来模拟这个请求。

import requests
import re

def extract_post_id_from_url(url):
    """
    从Haraj网站的URL中提取postId。
    示例: "https://haraj.com.sa/1194697687" -> 94697687
    """
    match = re.search(r'/(\d+)$', url)
    if match:
        full_id_str = match.group(1)
        # 根据观察,postId是URL末尾数字去除前两位"11"后的部分
        if full_id_str.startswith('11') and len(full_id_str) > 2:
            return int(full_id_str[2:])
        return int(full_id_str) # 如果没有"11"前缀,则直接返回
    return None

def get_hidden_phone_number(page_url):
    """
    通过模拟API请求获取隐藏的电话号码。
    """
    # 1. 从页面URL中提取 postId
    post_id = extract_post_id_from_url(page_url)
    if post_id is None:
        print(f"错误: 无法从URL '{page_url}' 中提取有效的 postId。")
        return None

    # 2. 定义API请求参数
    api_url = "https://graphql.haraj.com.sa"

    # 根据浏览器网络分析,这些参数可能为空或特定值
    params = {
        "queryName": "postContact",
        "token": "",
        "clientId": "",
        "version": ""
    }

    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36",
        "accept": "*/*",
        "accept-language": "en-US,en;q=0.9",
        "content-type": "application/json",
        "origin": "https://haraj.com.sa",
        "referer": page_url # 设置referer以模拟真实浏览器行为
    }

    # GraphQL请求的Payload
    payload = {   
        "query": "query postContact($postId: Int!) {postContact(postId: $postId){contactText}}",
        "variables": {
            "postId": post_id # 使用动态获取的postId
        }
    }

    try:
        # 3. 发送POST请求
        response = requests.post(api_url, params=params, headers=headers, json=payload)
        response.raise_for_status() # 检查HTTP请求是否成功

        # 4. 解析JSON响应
        data = response.json()

        # 提取电话号码
        contact_text = data.get('data', {}).get('postContact', {}).get('contactText')
        return contact_text

    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return None
    except KeyError as e:
        print(f"解析响应数据失败: 缺少键 {e}")
        return None

# 主函数调用示例
if __name__ == "__main__":
    target_page_url = "https://haraj.com.sa/1194697687" # 替换为实际的页面URL
    phone_number = get_hidden_phone_number(target_page_url)

    if phone_number:
        print(f"成功获取到电话号码: {phone_number}")
    else:
        print("未能获取电话号码。")

    # 另一个示例URL
    another_page_url = "https://haraj.com.sa/1199808969"
    phone_number_2 = get_hidden_phone_number(another_page_url)
    if phone_number_2:
        print(f"成功获取到另一个电话号码: {phone_number_2}")
    else:
        print("未能获取另一个电话号码。")

代码解释:

  • extract_post_id_from_url(url): 这个函数负责从给定的Haraj网站URL中解析出postId。它使用正则表达式匹配URL末尾的数字,并根据观察到的模式(去除前缀11)进行处理。
  • get_hidden_phone_number(page_url):
    • 首先调用extract_post_id_from_url获取当前页面的postId。
    • api_url:这是通过开发者工具识别出的GraphQL API的端点。
    • params:查询字符串参数,即使为空也应包含,以模拟浏览器行为。
    • headers:模拟浏览器请求头,特别是User-Agent、Content-Type、Origin和Referer,这有助于避免被网站识别为爬虫。
    • payload:这是一个字典,会被requests.post自动转换为JSON格式发送。它包含了GraphQL查询语句和动态的postId变量。
    • requests.post(...):发送POST请求。json=payload参数会自动设置Content-Type为application/json并序列化payload。
    • response.raise_for_status():这是一个好习惯,如果HTTP请求返回的状态码表示错误(例如4xx或5xx),它会抛出一个HTTPError。
    • response.json():将API返回的JSON响应解析为Python字典。
    • 通过字典的get方法安全地访问嵌套数据,提取contactText,即电话号码。
    • 增加了错误处理机制,捕获requests请求异常和JSON解析异常。

5. 注意事项与总结

  • 动态参数: 许多API请求中可能包含动态生成的令牌(token)、客户端ID(clientId)或会话ID。如果这些参数是必需的,你可能需要先爬取主页面,通过JavaScript代码或隐藏字段来提取它们。本例中的token、clientId和version在当前场景下似乎不是必需的,但实际情况可能不同。
  • User-Agent: 始终设置一个合理的User-Agent头部,以模拟真实浏览器,降低被网站封禁的风险。
  • 错误处理: 编写健壮的代码,处理网络请求失败、JSON解析失败或预期数据结构缺失等情况。
  • 频率限制与道德: 遵守网站的robots.txt协议,不要发送过高的请求频率,避免对目标网站造成不必要的负担。
  • GraphQL的优势: GraphQL允许客户端精确地指定所需的数据,这在某些情况下比REST API更高效,但也意味着你需要理解其查询语法。

通过上述方法,我们成功绕过了BeautifulSoup在处理动态加载内容时的局限性,直接与网站的后端API交互,高效准确地获取了隐藏的电话号码。这种模拟API请求的技术是爬取现代动态网站的关键技能之一。

热门AI工具

更多
音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

相关专题

更多
Python GraphQL API 开发实战
Python GraphQL API 开发实战

本专题系统讲解 Python 在 GraphQL API 开发中的实际应用,涵盖 GraphQL 基础概念、Schema 设计、Query 与 Mutation 实现、权限控制、分页与性能优化,以及与现有 REST 服务和数据库的整合方式。通过完整示例,帮助学习者掌握 使用 Python 构建高扩展性、前后端协作友好的 GraphQL 接口服务,适用于中大型应用与复杂数据查询场景。

209

2026.01.21

json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2115

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3202

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1076

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

3659

2025.09.10

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

4296

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

2821

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

7762

2023.07.05

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

0

2026.10.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebStorm 官方调试文档
WebStorm 官方调试文档

共0课时 | 0人学习

React 教程
React 教程

共58课时 | 12.2万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 6.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn