0

0

从动态网站抓取隐藏电话号码的实用教程

聖光之護

聖光之護

发布时间:2025-11-03 13:00:22

|

272人浏览过

|

来源于php中文网

原创

从动态网站抓取隐藏电话号码的实用教程

本教程旨在解决使用beautifulsoup抓取动态加载内容时的局限性。当目标数据(如隐藏的电话号码)通过javascript异步加载时,传统html解析器无法获取。文章将指导读者如何利用浏览器开发者工具识别并模拟网站后端api请求,特别是graphql请求,从而直接获取所需数据。通过python的requests库,我们将演示如何构建并发送http post请求,以高效、准确地抓取动态生成的内容。

理解动态内容抓取的挑战

在现代Web开发中,许多网站为了提供更流畅的用户体验,会采用JavaScript动态加载内容。这意味着当您使用像BeautifulSoup这样的HTML解析库去抓取一个页面时,您可能只会得到一个骨架HTML文档,而那些通过用户交互(例如点击按钮)或页面加载后异步加载的数据则无法直接获取。

以抓取一个隐藏在“联系”按钮后的电话号码为例。当用户点击该按钮时,JavaScript会执行一个操作,通常是向后端API发送请求,然后将返回的数据(如电话号码)插入到页面的DOM中。此时,如果仅依赖BeautifulSoup解析初始页面,您将无法找到这个电话号码,因为它尚未被渲染到HTML中。

识别API请求:开发者工具的妙用

解决动态内容抓取的关键在于识别并模拟网站向其后端API发出的请求。浏览器开发者工具是完成这项任务的强大助手。

  1. 打开开发者工具: 在Chrome、Firefox等浏览器中,按F12键或右键点击页面选择“检查”即可打开。
  2. 切换到“网络”(Network)选项卡: 这个选项卡会记录浏览器发出的所有HTTP请求。
  3. 筛选XHR/Fetch请求: 许多动态加载的数据是通过XMLHttpRequest (XHR) 或 Fetch API 发送的。在网络选项卡中,通常会有筛选器,选择“XHR”或“Fetch/XHR”可以只显示这些异步请求。
  4. 触发目标事件: 在本例中,您需要点击网站上的“التواصل”(联系)按钮。
  5. 检查请求详情: 点击按钮后,网络选项卡中会出现一个新的请求。检查这个请求的以下信息:
    • 请求URL (Request URL): API的端点。
    • 请求方法 (Request Method): 通常是GET或POST。
    • 请求头 (Request Headers): 包含User-Agent、Content-Type等。
    • 请求负载 (Request Payload): 如果是POST请求,这里会包含发送给服务器的数据,通常是JSON格式。对于GraphQL API,这里会包含查询语句和变量。
    • 响应 (Response): 服务器返回的数据,通常是JSON格式,其中包含您需要的信息。

通过分析这些信息,我们可以精确地复现浏览器与服务器之间的通信过程。

模拟API请求:使用Python requests

一旦我们确定了API请求的细节,就可以使用Python的requests库来模拟这些请求。

核心思路

对于本例,我们发现网站使用GraphQL API。这意味着我们需要向一个特定的GraphQL端点发送一个HTTP POST请求,并在请求体中包含一个GraphQL查询语句和相应的变量。

实施步骤

  1. 导入 requests 库:

    import requests
  2. 定义API端点: 这是您从开发者工具中识别出的请求URL。

    DK企业网站管理系统1.1
    DK企业网站管理系统1.1

    后台路径网址+admin(请修改更安全)后台用户名密码admin产品定位:中小型企业,本系统简单实用,无冗余功能,无功能限制。后台功能:一、网站基本信息此功能允许您从后台设置网站的名称、联系人、电话、公司地址、版权、第三方统计代码等等常用信息。二、导航栏设置可以从后台调整导航栏显示项目,可以进行增加删除排序隐藏导航栏等操作三、幻灯设置可以从后台设置前台动画轮播图片,支持排序。四、单页功能用来设置公

    下载
    url = "https://graphql.haraj.com.sa"
  3. 设置请求头: 至少包含一个User-Agent,以模拟浏览器行为。

    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"
    }
  4. 构建查询参数(可选): 有些API请求URL中会包含查询参数。根据开发者工具的观察,本例中的GraphQL API在URL中包含了一些参数,但实际测试发现,即使不提供这些参数,API也能正常响应。为了教程的完整性,可以定义但留空或根据实际情况填充。

    params = {
        "queryName": "postContact",
        "token": "",
        "clientId": "",
        "version": ""
    }

    注意: 实际操作中,token和clientId等参数可能需要从原始页面或其他API请求中动态获取,或者可能不是必需的。在本例中,它们似乎不是强制性的。

  5. 构建请求负载(Payload): 这是最重要的部分,尤其是对于GraphQL API。它是一个JSON对象,包含query(GraphQL查询语句)和variables(查询所需的变量)。

    payload = {   
        "query": "query postContact($postId: Int!) {postContact(postId: $postId){contactText}}",
        "variables": {
            "postId": 94697687 # 这个ID通常从原始页面URL中提取
        }
    }
    • query: 定义了我们想要执行的GraphQL操作,这里是postContact查询,它接受一个postId参数并返回contactText。
    • variables: 提供了postId的值。这个postId通常可以从原始页面的URL中提取出来。例如,如果原始URL是https://haraj.com.sa/1194697687,那么postId就是94697687。
  6. 发送POST请求: 使用requests.post()方法,将URL、参数、头部和JSON负载传递进去。json=payload会自动设置Content-Type为application/json

    response = requests.post(url, params=params, headers=headers, json=payload)
  7. 处理响应:

    • 检查状态码: 使用response.raise_for_status()可以检查请求是否成功(状态码200)。如果不是,它会抛出HTTPError异常。
    • 解析JSON数据: 使用response.json()将响应体解析为Python字典。
    • 提取所需信息: 从解析后的字典中提取电话号码。

完整代码示例

import requests
import sys

def scrape_phone_number(post_id):
    """
    通过模拟GraphQL API请求从Haraj网站抓取电话号码。

    Args:
        post_id (int): 帖子的ID,通常从帖子URL中提取。

    Returns:
        str: 提取到的电话号码,如果失败则返回None。
    """
    url = "https://graphql.haraj.com.sa"

    # 根据实际情况,这些参数可能需要动态获取或并非必需
    params = {
        "queryName": "postContact",
        "token": "",
        "clientId": "",
        "version": ""
    }

    headers = {
        # 建议使用完整的User-Agent字符串以更好地模拟浏览器
        "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"
    }

    payload = {   
        "query": "query postContact($postId: Int!) {postContact(postId: $postId){contactText}}",
        "variables": {
            "postId": post_id
        }
    }

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

        data = response.json()
        # 从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:
        print("从API响应中解析数据失败,可能结构不符。")
        return None

if __name__ == "__main__":
    # 示例:从帖子URL https://haraj.com.sa/1194697687 中提取postId
    example_post_id = 94697687 

    phone_number = scrape_phone_number(example_post_id)

    if phone_number:
        print(f"抓取到的电话号码是: {phone_number}")
    else:
        print("未能抓取到电话号码。")

    sys.exit(0)

输出示例

抓取到的电话号码是: 0562038953

注意事项与最佳实践

  1. 动态获取 postId: 在实际应用中,postId不应硬编码。您需要首先使用BeautifulSoup或其他方法从原始页面URL中解析出这个ID。例如,从 https://haraj.com.sa/1194697687 中提取 94697687。
  2. 错误处理: 务必包含健壮的错误处理机制,例如try-except块来捕获requests.exceptions.RequestException和KeyError,以应对网络问题或API响应格式变化。
  3. User-Agent: 始终在请求头中设置User-Agent。模拟常用浏览器可以降低被网站识别为爬虫的风险。
  4. API参数变化: 网站API可能会更新,导致params或payload结构发生变化。定期检查开发者工具以确保您的代码与最新API保持同步。
  5. 频率限制与IP封锁: 大量、快速的请求可能会触发网站的频率限制或导致您的IP被封锁。在实际抓取时,应加入适当的延迟(time.sleep())和代理IP轮换机制。
  6. GraphQL的灵活性: GraphQL允许客户端指定所需的数据字段。在query中,只请求您真正需要的数据可以提高效率。

总结

当传统的HTML解析方法(如BeautifulSoup)无法获取动态加载的内容时,通过模拟网站的后端API请求是更强大、更直接的解决方案。利用浏览器开发者工具分析网络流量,识别API端点、请求方法、头部和负载,然后使用Python的requests库精确地复现这些请求,可以有效地抓取到隐藏在动态交互背后的数据。这种方法不仅适用于电话号码,也适用于任何通过JavaScript异步加载的数据。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

769

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

661

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

764

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

639

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1325

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

549

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

579

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

709

2023.08.11

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

9

2026.01.21

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.9万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.3万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号