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

本教程旨在解决使用beautifulsoup抓取动态加载内容时的局限性。当目标数据(如隐藏的电话号码)通过j*ascript异步加载时,传统html解析器无法获取。文章将指导读者如何利用浏览器开发者工具识别并模拟网站后端api请求,特别是graphql请求,从而直接获取所需数据。通过python的requests库,我们将演示如何构建并发送http post请求,以高效、准确地抓取动态生成的内容。
理解动态内容抓取的挑战
在现代Web开发中,许多网站为了提供更流畅的用户体验,会采用J*aScript动态加载内容。这意味着当您使用像BeautifulSoup这样的HTML解析库去抓取一个页面时,您可能只会得到一个骨架HTML文档,而那些通过用户交互(例如点击按钮)或页面加载后异步加载的数据则无法直接获取。
以抓取一个隐藏在“联系”按钮后的电话号码为例。当用户点击该按钮时,J*aScript会执行一个操作,通常是向后端API发送请求,然后将返回的数据(如电话号码)插入到页面的DOM中。此时,如果仅依赖BeautifulSoup解析初始页面,您将无法找到这个电话号码,因为它尚未被渲染到HTML中。
识别API请求:开发者工具的妙用
解决动态内容抓取的关键在于识别并模拟网站向其后端API发出的请求。浏览器开发者工具是完成这项任务的强大助手。
- 打开开发者工具: 在Chrome、Firefox等浏览器中,按F12键或右键点击页面选择“检查”即可打开。
- 切换到“网络”(Network)选项卡: 这个选项卡会记录浏览器发出的所有HTTP请求。
- 筛选XHR/Fetch请求: 许多动态加载的数据是通过XMLHttpRequest (XHR) 或 Fetch API 发送的。在网络选项卡中,通常会有筛选器,选择“XHR”或“Fetch/XHR”可以只显示这些异步请求。
- 触发目标事件: 在本例中,您需要点击网站上的“التواصل”(联系)按钮。
-
检查请求详情: 点击按钮后,网络选项卡中会出现一个新的请求。检查这个请求的以下信息:
- 请求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查询语句和相应的变量。
实施步骤
-
导入 requests 库:
import requests
-
定义API端点: 这是您从开发者工具中识别出的请求URL。
DK企业网站管理系统1.1
后台路径网址+admin(请修改更安全)后台用户名密码admin产品定位:中小型企业,本系统简单实用,无冗余功能,无功能限制。后台功能:一、网站基本信息此功能允许您从后台设置网站的名称、联系人、电话、公司地址、版权、第三方统计代码等等常用信息。二、导航栏设置可以从后台调整导航栏显示项目,可以进行增加删除排序隐藏导航栏等操作三、幻灯设置可以从后台设置前台动画轮播图片,支持排序。四、单页功能用来设置公
0
查看详情
url = "https://graphql.haraj.com.sa"
-
设置请求头: 至少包含一个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" } -
构建查询参数(可选): 有些API请求URL中会包含查询参数。根据开发者工具的观察,本例中的GraphQL API在URL中包含了一些参数,但实际测试发现,即使不提供这些参数,API也能正常响应。为了教程的完整性,可以定义但留空或根据实际情况填充。
params = { "queryName": "postContact", "token": "", "clientId": "", "version": "" }注意: 实际操作中,token和clientId等参数可能需要从原始页面或其他API请求中动态获取,或者可能不是必需的。在本例中,它们似乎不是强制性的。
-
构建请求负载(
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。
-
发送POST请求: 使用requests.post()方法,将URL、参数、头部和JSON负载传递进去。json=payload会自动设置Content-Type为application/json。
response = requests.post(url, params=params, headers=headers, json=payload)
-
处理响应:
- 检查状态码: 使用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
注意事项与最佳实践
- 动态获取 postId: 在实际应用中,postId不应硬编码。您需要首先使用BeautifulSoup或其他方法从原始页面URL中解析出这个ID。例如,从 https://haraj.com.sa/1194697687 中提取 94697687。
- 错误处理: 务必包含健壮的错误处理机制,例如try-except块来捕获requests.exceptions.RequestException和KeyError,以应对网络问题或API响应格式变化。
- User-Agent: 始终在请求头中设置User-Agent。模拟常用浏览器可以降低被网站识别为爬虫的风险。
- API参数变化: 网站API可能会更新,导致params或payload结构发生变化。定期检查开发者工具以确保您的代码与最新API保持同步。
- 频率限制与IP封锁: 大量、快速的请求可能会触发网站的频率限制或导致您的IP被封锁。在实际抓取时,应加入适当的延迟(time.sleep())和代理IP轮换机制。
- GraphQL的灵活性: GraphQL允许客户端指定所需的数据字段。在query中,只请求您真正需要的数据可以提高效率。
总结
当传统的HTML解析方法(如BeautifulSoup)无法获取动态加载的内容时,通过模拟网站的后端API请求是更强大、更直接的解决方案。利用浏览器开发者工具分析网络流量,识别API端点、请求方法、头部和负载,然后使用Python的requests库精确地复现这些请求,可以有效地抓取到隐藏在动态交互背后的数据。这种方法不仅适用于电话号码,也适用于任何通过J*aScript异步加载的数据。
以上就是从动态网站抓取隐藏电话号码的实用教程的详细内容,更多请关注其它相关文章!
# python
# java
# html
# js
# json
# windows
# 编码
# javascript
# 这是
# 济南seo搜索排名怎么查
# 您的
# 石家庄智能网站建设排名
# 工程网站建设特点包括
# 温州网站建设推广推荐
# 佛山医疗网站建设推广
# 怎么改善seo专注页面
# 临海seo软件排名靠前
# 铁岭seo软件怎么操作
# 珠海网站建设开发费用
# 网站推广计划大纲
# 后端
# 本例
# 选项卡
# 企业网站
# 置顶
# 所需
# 管理系统
# 加载
# sa
# 工具
# app
# 浏览器
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
基于动态规划的房屋花卉种植最小成本算法详解
Yandex官方入口网址 Yandex俄罗斯搜索引擎最新在线地址
LINQ to XML为何解析失败? 深入理解C# XDocument的异常处理
QQ邮箱网页版入口页面 QQ邮箱在线登录入口官网
C++如何实现一个智能指针_手动实现C++ shared_ptr的引用计数功能
魅族20怎样在浏览器开无图省流_iPhone魅族20浏览器开无图省流【流量节省】
神庙逃亡小游戏在线玩 神庙逃亡小游戏入口
b站怎么删除评论_b站评论管理与删除操作
品牌机怎么重装系统 联想/戴尔/惠普笔记本恢复出厂系统教程
Win11怎么开启高性能模式_Windows 11电源计划优化设置
在J*a中如何使用Exception包装底层异常_异常包装与信息传递方法说明
QQ邮箱官网登录入口 QQ邮箱网页版邮箱快速登录
CSS Flexbox如何实现多行排列_flex-wrap wrap自动换行显示
妖精动漫免费平台 妖精动漫官网资源观看网址
Yandex搜索引擎一键访问入口_俄罗斯Yandex官网免登录
J*aScript打印功能_j*ascript输出控制
铁路12306的积分有效期是多久_铁路12306积分有效期说明
Lar*el头像管理:图片缩放与旧文件删除的最佳实践
Composer中的^和~符号代表什么_精通Composer版本号语义化约束
网站内容防复制粘贴的实现策略与局限性
Win11如何开启讲述人功能 Win11屏幕阅读器(讲述人)开启与关闭【教程】
J*aScript设计模式实践_j*ascript代码优化
Go与Ruby之间实现AES加密互通:CFB模式下的密钥长度匹配策略
Django AJAX 文件上传教程:解决图片无法保存到模型的常见问题
微博网页版官方账号登录 微博网页版内容浏览使用指南
LINUX怎么设置定时任务_LINUX crontab配置教程
Golang并发任务中错误如何聚合_Golang goroutine error收集方式
Windows10怎么开启存储感知 Windows10系统设置自动清理临时文件释放C盘空间【教程】
c++中的std::launder有什么实际用途_c++对象生命周期与指针优化
Python多版本共存与虚拟环境管理深度指南
AO3中文官网链接_AO3网页版稳定镜像站
TikTok搜索结果不显示如何解决 TikTok搜索刷新优化方法
sublime怎么进行远程开发编辑_配置rsub/rmate实现sublime编辑服务器文件
快手网页版在线登录 快手网页版官网入口快速访问
Pandas DataFrame:高效添加条件计算列
荣耀Play7T运行卡顿解决_荣耀Play7T性能优化
Win11怎么设置鼠标指针速度_Win11提高鼠标指针精确度选项
Yandex官网免登录入口_俄罗斯Yandex搜索引擎一键访问
HTML元素状态管理:根据DIV内容动态启用/禁用按钮
我的世界mc.js免费游戏直接能玩 我的世界mc.js小游戏免费秒玩入口
J*aScript实现单选按钮与关联输入框的联动禁用教程
韩小圈电脑版在线入口_网页版免费登录地址
Spring Boot内嵌服务器与J*a EE全栈特性:选择与部署策略
Win10文件资源管理器“此电脑”分组怎么关 Win10恢复经典视图【技巧】
零跑汽车11月交付量达70327台 实现连续9个月正增长
CSS响应式网页如何实现主次模块比例自适应_flex-grow与flex-shrink调整
Python中高效且防溢出的双曲正弦计算:基于对数空间的优化策略
PrimeNG Sidebar背景色自定义指南:CSS覆盖与主题化实践
汽水音乐车机版横屏版7.1 汽水音乐车机版横屏版下载入口
Win11怎么用U盘重装系统 Win11制作启动盘并重装系统完整教程【详解】


2025-11-03
浏览次数:次
返回列表
Payload): 这是最重要的部分,尤其是对于GraphQL API。它是一个JSON对象,包含query(GraphQL查询语句)和variables(查询所需的变量)。