Python爬取动态加载内容的电话号码:直击GraphQL API获取隐藏数据


Python爬取动态加载内容的电话号码:直击GraphQL API获取隐藏数据

本教程旨在解决使用python爬取网站上动态加载的隐藏电话号码问题。当传统html解析(如beautifulsoup)无法获取点击按钮后才显示的内容时,通常是因为数据通过j*ascript异步请求加载。我们将深入探讨如何利用浏览器开发者工具识别并模拟这些api请求(特别是graphql post请求),从而直接获取所需数据,避免复杂的浏览器自动化。

在现代网页开发中,许多内容并非在初始HTML加载时就全部呈现,而是通过J*aScript在用户交互(如点击按钮)后动态获取并填充到页面中。对于这类隐藏在交互背后的数据,仅仅使用像BeautifulSoup这样的HTML解析库去处理初始页面内容是远远不够的。本教程将指导您如何绕过前端交互,直接通过模拟API请求来获取这些动态加载的数据。

理解动态内容加载机制

当您在网页上点击一个按钮,而内容随之出现时,浏览器通常会向服务器发起一个异步请求(XHR或Fetch请求)。服务器响应的数据(通常是JSON格式)随后被J*aScript处理并插入到DOM中。这意味着,您在浏览器中看到的内容,可能并不是通过简单的requests.get()就能获取到的原始HTML所包含的。

要成功爬取这类数据,关键在于识别并复现浏览器发起的这个异步请求。

识别目标API请求

这是解决问题的核心步骤,需要借助浏览器的开发者工具:

  1. 打开目标网页: 在Chrome、Firefox等浏览器中打开您想要爬取数据的页面。
  2. 打开开发者工具: 按F12或右键点击页面选择“检查”/“审查元素”,然后切换到“网络”(Network)选项卡。
  3. 清除网络日志: 在“网络”选项卡中,通常有一个清除按钮(一个圆圈带斜杠的图标),点击它可以清空之前的网络请求记录,方便我们观察新的请求。
  4. 模拟用户交互: 点击页面上显示隐藏内容的按钮(例如本例中的“التواصل”按钮)。
  5. 观察网络请求: 在“网络”选项卡中,您会看到一系列新的请求。仔细查找那些响应类型为json或方法为POST的请求。
    • 筛选: 可以使用过滤器(例如输入graphql或json)来缩小范围。
    • 检查请求详情: 点击可疑的请求,查看其“标头”(Headers)、“负载”(Payload/Request Body)和“响应”(Response)选项卡。
      • URL: 记录请求的URL。
      • 方法: 确认是GET还是POST。对于动态内容,POST请求尤其常见,特别是针对GraphQL API。
      • 请求标头(Request Headers): 至少需要复制User-Agent,有时还需要Content-Type、Referer等。
      • 请求负载(Request Payload): 这是POST请求的主体,对于GraphQL请求,它通常包含query和variables字段,其中variables会包含像postId这样的动态参数。
      • 响应(Response): 确认响应数据中是否包含您需要的信息(例如电话号码)。

在本例中,我们发现点击按钮后,浏览器向https://graphql.haraj.com.sa发起了一个POST请求,其负载包含一个GraphQL查询。

使用Python模拟API请求

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

度加剪辑 度加剪辑

度加剪辑(原度咔剪辑),百度旗下AI创作工具

度加剪辑 359 查看详情 度加剪辑
import requests
import sys

def get_phone_number_via_api(post_id: int) -> str:
    """
    通过模拟GraphQL API请求获取指定帖子的电话号码。

    Args:
        post_id: 帖子ID,通常可以从页面URL中提取。

    Returns:
        电话号码字符串,如果获取失败则返回空字符串。
    """
    url = "https://graphql.haraj.com.sa"

    # 查询字符串参数,本例中API比较宽松,可为空
    params = {
        "queryName": "postContact",
        "token": "",
        "clientId": "",
        "version": ""
    }

    # 请求头部,至少包含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."
    }

    # POST请求的JSON负载,包含GraphQL查询和变量
    payload = {   
        "query": "query postContact($postId: Int!) {postContact(postId: $postId){contactText}}",
        "variables": {
            "postId": post_id  # 动态传入帖子ID
        }
    }

    try:
        # 发送POST请求,json参数会自动设置Content-Type为application/json
        response = requests.post(url, params=params, headers=headers, json=payload)
        response.raise_for_status()  # 检查HTTP请求是否成功(状态码200)

        # 解析JSON响应
        data = response.json()
        phone_number = data.get('data', {}).get('postContact', {}).get('contactText')

        if phone_number:
            return phone_number
        else:
            print(f"未能从响应中提取电话号码: {data}")
            return ""

    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return ""
    except ValueError as e:
        print(f"JSON解析失败: {e}")
        return ""

def main():
    # 示例帖子ID,从URL https://haraj.com.sa/1194697687 中提取 94697687
    # 注意:原始URL中的 1194697687 经过观察,实际API请求中使用的 postId 是 94697687
    example_post_id = 94697687 

    print(f"正在获取帖子ID {example_post_id} 的电话号码...")
    phone_number = get_phone_number_via_api(example_post_id)

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

    return 0

if __name__ == "__main__":
    sys.exit(main())

代码解释:

  • requests.post(url, params=params, headers=headers, json=payload): 这是发送POST请求的关键。
    • url: GraphQL API的端点。
    • params: URL的查询字符串参数。在本例中,虽然提供了,但API似乎很宽松,即使为空也能工作。在其他场景下,这些参数可能至关重要。
    • headers: 请求头,User-Agent是模拟浏览器行为的最低要求,防止被网站屏蔽。
    • json: 用于发送JSON格式的请求体。requests库会自动设置Content-Type: application/json。对于GraphQL,payload通常包含query(GraphQL查询语句)和variables(查询中使用的动态参数)。
  • response.raise_for_status(): 这是一个好习惯,它会在HTTP请求返回错误状态码(如4xx或5xx)时抛出requests.exceptions.HTTPError,方便错误处理。
  • response.json(): 将API响应解析为Python字典。
  • 数据提取: 使用get()方法安全地从嵌套字典中提取数据,避免KeyError。

运行结果

执行上述代码,您将获得类似以下的输出:

正在获取帖子ID 94697687 的电话号码...
获取到的电话号码是: 0562038953

这表明我们成功地通过直接调用API获取了隐藏的电话号码。

注意事项与总结

  1. BeautifulSoup的定位: BeautifulSoup仍然是解析静态HTML的强大工具。对于动态加载的内容,它在获取初始页面结构后就无能为力了。
  2. Selenium的适用场景: 如果网站的反爬机制非常复杂,或者需要模拟更复杂的浏览器交互(如拖拽验证码、复杂的JS事件监听),Selenium等自动化测试工具可能是必要的。但对于本例,直接API调用更高效、资源消耗更少。
  3. API稳定性: 直接调用API意味着您依赖于目标网站的API结构。如果API发生变化,您的爬虫可能会失效。
  4. 道德与法律: 在进行任何网络爬取活动时,请务必遵守网站的robots.txt文件、服务条款以及当地的法律法规。避免对网站造成过大负担。
  5. 错误处理: 在实际项目中,务必加入健壮的错误处理机制,例如重试逻辑、日志记录等。
  6. postId的提取: 在本例中,postId 94697687是从原始URL https://haraj.com.sa/1194697687中观察到的。通常,您需要编写代码从页面的URL或其他元素中动态提取这个ID。

通过本教程,您应该掌握了如何通过分析网络请求并直接调用API来爬取动态加载内容的技巧。这种方法对于许多现代网站上的隐藏数据(如电话号码、商品价格、用户评论等)都非常有效。

以上就是Python爬取动态加载内容的电话号码:直击GraphQL API获取隐藏数据的详细内容,更多请关注其它相关文章!


# python  # javascript  # sa  # 工具  # app  # 浏览器  # windows  # json  # 前端  # js  # html  # java  # 东营seo优化什么价格  # 石家庄网站优化照片公司  # 无锡营销推广活动策划  # 靠谱的关键词排名方案  # 邢台抖音网站建设优势  # 辽阳推广平台招聘网站大全  # 太原网站建设的定位是  # 大沥seo推广  # 新密专业网站建设  # 保定网站推广蔚芯hfqjwl下拉  # 直接调用  # 双击  # 解决问题  # 您在  # 这类  # 直击  # 选项卡  # 这是  # 本例  # 加载 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: Cassandra中复合主键、二级索引与ORDER BY排序的限制与解决方案  腾讯QQ邮箱官方入口 QQ邮箱网页版登录平台  Win11便笺在哪打开 Win11桌面便笺(Sticky Notes)使用方法【详解】  苹果手机手电筒无法开启  J*aScript装饰器_元编程实战  GBA模拟器手柄按键设置  键盘测试软件哪个好_键盘故障检测工具推荐  附近酒吧怎么找?  《下一站江湖2》心法融合技巧  QQ网页版入口导航 QQ网页版在线访问通道  《东方财富》条件单关闭方法  在VS Code中利用AI辅助进行代码迁移  泰拉瑞亚水晶无法放置问题  Scipy Sparse CSR 矩阵非零元素行级遍历的最佳实践  如何解决Casbin日志与应用日志不统一的问题,使用casbin/psr3-bridge实现无缝集成  Composer reinstall命令重装损坏的包  手机雨课堂网页版入口免登录 雨课堂网页版可点击直接进入  Final Cut Pro视频加EQ教程  智学网app怎么登录忘记密码_智学网app忘记密码找回与重新登录操作方法  《微信》视频号原创声明开启方法  我的世界官方网址入口 我的世界游戏主页直达入口  iPhone 15 Pro如何查看存储空间占用_iPhone 15 Pro存储空间查看教程  HTML与J*aScript实现下拉菜单驱动的动态表格:构建交互式维修表单  获取WooCommerce产品在后台编辑页面的分类ID  汽水音乐车机版 汽水音乐车机版官方入口  解决CSS background 属性中 cover 关键字的常见误用  键盘声音异常怎么回事_键盘异响怎么处理  解决J*aScript动态图片上传中ID重复问题:在同一页面显示多张独立图片  大熊猫抓取竹子的“大拇指”其实是什么?蚂蚁庄园课堂今天答案最新11月30日  iPhone12是否要更新ios16  利用Flexbox实现图片元素的二维布局:2x2网格排列指南  Golang如何测试结构体方法_Golang reflect方法测试与调用技巧  小米手机屏幕失灵乱跳怎么办 屏幕触控问题自检与临时解决方法【应急】  C++ static关键字作用_C++静态成员变量与静态函数  《360浏览器》设置摄像头权限方法  悟空浏览器网页版在线工具 悟空浏览器网页版在线平台入口  苹果SE如何开启单手模式_苹果SE单手操作功能  谷歌浏览器官方镜像获取方法_谷歌浏览器网页版入口极速直达  除了Copilot,还有哪些值得一试的VS Code AI插件?  Lar*el Socialite单设备登录策略:实现用户唯一会话管理  如何在vscode中关闭it环境  c++如何使用std::thread::join和detach_c++线程生命周期管理  英雄联盟争者留名活动介绍  汽水音乐车机版官网5.0 汽水音乐车机版5.0版本下载入口  折叠屏手机充不进电是什么问题? 特殊结构带来的维修难点  解决VS Code中Python版本冲突与输出异常的指南  不吃碳水化合物是健康减肥的好办法吗  OTT月报 | 2025年9月智能电视大数据报告  CSS过渡如何实现按钮悬停效果_transition属性控制背景颜色变化  店铺如何关联视频号推广?视频号推广有什么用? 

 2025-11-03

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.