
本文将指导读者如何使用python从动态加载的网页弹出按钮中抓取隐藏的电话号码。针对beautifulsoup无法处理javascript动态内容的局限性,我们将采用直接模拟浏览器底层api请求的方法,通过分析网络流量,重构post请求,并解析json响应,高效地获取目标数据,避免了使用重量级自动化工具如selenium的复杂性。
在网络爬虫实践中,我们经常会遇到内容并非直接嵌入在初始HTML中的情况。许多现代网站利用JavaScript动态加载数据,例如通过点击按钮弹出的对话框、无限滚动页面或异步更新的内容。对于这类场景,传统的HTML解析库如BeautifulSoup仅能处理请求获得的静态HTML内容,而无法执行JavaScript来渲染或加载动态数据。
例如,当尝试抓取一个只有在点击“联系方式”或“查看电话”按钮后才显示电话号码的网站时,如果仅使用BeautifulSoup,你可能会发现按钮对应的HTML元素中并不包含电话号码,而是一个占位符或触发JavaScript函数的代码。此时,BeautifulSoup的输出将只包含按钮本身,而无法获取到点击后才出现的信息。
虽然Selenium等工具可以模拟完整的浏览器行为,包括执行JavaScript和点击元素,但对于仅需获取特定动态加载数据的情形,Selenium往往显得过于重量级,会增加额外的开销和复杂性。更高效的方法是直接识别并模拟浏览器用于获取这些动态数据的底层API请求。
获取动态加载数据的关键在于理解浏览器在后台是如何获取这些数据的。通常,当用户在网页上进行交互(如点击按钮)时,浏览器会向服务器发送一个异步请求(XHR/Fetch请求),服务器返回数据(通常是JSON格式),然后JavaScript再将这些数据渲染到页面上。
立即学习“Python免费学习笔记(深入)”;
要识别这些API请求,你需要使用浏览器的开发者工具:
通过分析,你会发现本例中电话号码数据是通过向 https://graphql.haraj.com.sa 发送一个POST请求,并携带一个GraphQL查询作为请求体来获取的。
一旦识别出API请求的所有细节,我们就可以使用Python的requests库来模拟这个请求。
import requests
import sys
def scrape_phone_number(post_id: int):
    """
    通过模拟API请求从Haraj网站抓取指定帖子的电话号码。
    Args:
        post_id (int): 帖子的唯一标识符。
    Returns:
        str: 提取到的电话号码,如果失败则返回None。
    """
    # GraphQL API的端点URL
    url = "https://graphql.haraj.com.sa"
    # 请求参数 (query string parameters)
    # 示例中这些参数可以为空,表示API可能对它们不敏感或有默认值
    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"
    }
    # 请求体 (payload),包含GraphQL查询和变量
    # 注意:'postId' 是动态获取电话号码的关键参数
    payload = {   
        "query": "query postContact($postId: Int!) {postContact(postId: $postId){contactText}}",
        "variables": {
            "postId": post_id
        }
    }
    try:
        # 发送POST请求,requests库会自动将payload转换为JSON格式
        response = requests.post(url, params=params, headers=headers, json=payload)
        # 检查HTTP状态码,如果不是2xx则抛出异常
        response.raise_for_status()
        # 解析JSON响应
        data = response.json()
        # 从JSON数据中提取电话号码
        contact_text = data.get('data', {}).get('postContact', {}).get('contactText')
        if contact_text:
            print(f"成功获取电话号码: {contact_text}")
            return contact_text
        else:
            print("未在响应中找到电话号码。")
            return None
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return None
    except ValueError as e:
        print(f"JSON解析失败: {e}")
        return None
if __name__ == "__main__":
    # 示例帖子ID,这个ID通常需要从原始网页URL或HTML中提取
    # 例如,如果原始URL是 https://haraj.com.sa/1194697687,则 postId 可能是 94697687
    example_post_id = 94697687 
    phone_number = scrape_phone_number(example_post_id)
    if phone_number:
        print(f"最终提取的电话号码是: {phone_number}")
    else:
        print("未能提取电话号码。")
    sys.exit(0)
当面对JavaScript动态加载内容的网站时,BeautifulSoup等静态HTML解析器会力不从心。此时,直接模拟浏览器底层的API请求是一种更高效、更直接的解决方案。通过熟练运用浏览器开发者工具分析网络流量,识别API端点、请求方法、请求头和请求体,我们可以精确地使用Python的requests库重构这些请求,从而绕过复杂的页面渲染过程,直接获取所需数据。这种方法不仅避免了Selenium的额外开销,也为处理各种动态网页爬取任务提供了强大的工具。
以上就是使用Python绕过动态加载:从弹出按钮中抓取隐藏电话号码的API方法的详细内容,更多请关注php中文网其它相关文章!
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
                
                                
                                
                                
                                
                                
                                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号