0

0

使用Requests和BeautifulSoup解析动态内容与处理邮件混淆技术

DDD

DDD

发布时间:2025-11-30 12:12:28

|

571人浏览过

|

来源于php中文网

原创

使用requests和beautifulsoup解析动态内容与处理邮件混淆技术

本教程深入探讨了在使用Python的`requests`和`BeautifulSoup`库进行网页抓取时,如何有效处理通过JavaScript动态加载或混淆的电子邮件地址。文章将展示当直接HTML解析无法获取目标数据时,如何通过解析页面中嵌入的JSON数据(例如来自`__NEXT_DATA__`脚本标签)来成功提取姓名、位置、网站以及关键的电子邮件信息。

网页抓取中的常见挑战:动态内容与数据混淆

在进行网页抓取(Web Scraping)时,开发者经常会遇到一些挑战,其中最常见的包括动态加载的内容和为了防止自动化抓取而进行的数据混淆。传统的requests和BeautifulSoup组合在处理静态HTML内容时非常高效,但当目标数据不是直接存在于初始HTML响应中,而是通过JavaScript在客户端渲染,或者像电子邮件地址一样被故意混淆时,就需要更高级的策略。

一个典型的例子是电子邮件地址的混淆。网站为了保护用户的电子邮件不被垃圾邮件机器人抓取,常常会使用各种技术,如将电子邮件地址编码、使用JavaScript动态生成,或者将其嵌入到不可见的脚本块中。当直接尝试通过CSS选择器或标签查找电子邮件时,往往会发现一个类似/cdn-cgi/l/email-protection的链接或者一个带有特殊类的占位符,而不是真实的电子邮件地址。

初始尝试与遇到的问题

考虑以下使用requests和BeautifulSoup抓取特定网页信息的Python代码片段:

from bs4 import BeautifulSoup
import requests

url = 'https://www.kw.com/agent/UPA-6587385179144187908-1'
res = requests.get(url)
soup = BeautifulSoup(res.content,'html.parser')

name  = soup.find('div',class_='AgentContent__name').text.strip()
location = soup.find('div',class_='AgentContent__location').text.strip()
website = soup.find('a',class_='AgentInformation__factBody').attrs['href']

print(f"姓名: {name}")
print(f"位置: {location}")
print(f"网站: {website}")

这段代码能够成功提取姓名、位置和网站链接。然而,如果尝试以类似的方式提取电子邮件地址,例如通过查找一个带有特定类名的标签,结果可能会是这样的:

/cdn-cgi/l/email-protection#f18394909d94828590859482b199949895989093949d94df929e9c

这显然不是一个可用的电子邮件地址,而是一个由CDN服务(如Cloudflare)提供的电子邮件保护机制。这意味着真实的电子邮件地址并没有直接以明文形式存在于我们通过requests.get()获取的HTML中。

解决方案:深入解析页面中的JSON数据

当直接解析HTML元素无法获取所需数据时,一个有效的策略是检查页面中是否包含以JSON格式嵌入的数据。许多现代的JavaScript框架(如Next.js、React等)在服务器端渲染(SSR)或静态生成(SSG)时,会将页面所需的数据预加载到一个特殊的

步骤一:定位并提取JSON数据

首先,我们需要使用BeautifulSoup找到包含JSON数据的

Copy.ai
Copy.ai

Copy.ai 是一个人工智能驱动的文案生成器

下载
import requests
from bs4 import BeautifulSoup
import json

url = 'https://www.kw.com/agent/UPA-6587385179144187908-1'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')

# 查找id为__NEXT_DATA__的script标签
script_tag = soup.find('script', {'id': '__NEXT_DATA__'})

if script_tag:
    # 提取script标签的文本内容
    json_data_str = script_tag.get_text()
    # 将JSON字符串解析为Python字典
    json_data = json.loads(json_data_str)
else:
    print("未找到__NEXT_DATA__脚本标签。")
    exit()

步骤二:导航JSON结构提取目标信息

一旦我们将JSON字符串解析为Python字典,就可以像操作普通字典一样,通过键(keys)来导航其结构,直到找到我们所需的信息。这通常需要一些探索,通过打印json_data或使用在线JSON查看器来理解其结构。

根据目标网站的结构,我们可以发现代理商的信息(包括姓名、城市、州、电子邮件和网站)嵌套在json_data['props']['pageProps']['agentData']路径下。

# 从解析后的JSON数据中提取信息
try:
    agent_data = json_data['props']['pageProps']['agentData']
    name = agent_data['name']['full']
    city = agent_data['location']['city']
    state = agent_data['location']['state']
    email = agent_data['email']
    website = agent_data['website']

    print(f"姓名: {name}")
    print(f"城市: {city}")
    print(f"州: {state}")
    print(f"电子邮件: {email}")
    print(f"网站: {website}")

except KeyError as e:
    print(f"从JSON数据中提取信息失败,缺少键: {e}")

完整示例代码

结合上述步骤,以下是完整的Python代码,用于从目标网页中成功提取姓名、城市、州、电子邮件和网站:

import requests
from bs4 import BeautifulSoup
import json

def scrape_agent_info(url):
    """
    从指定URL抓取代理商信息,包括姓名、城市、州、电子邮件和网站。
    """
    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status() # 检查HTTP请求是否成功
    except requests.exceptions.RequestException as e:
        print(f"请求URL失败: {e}")
        return None

    soup = BeautifulSoup(response.text, 'lxml')

    script_tag = soup.find('script', {'id': '__NEXT_DATA__'})

    if not script_tag:
        print("未找到__NEXT_DATA__脚本标签,可能该网站未使用Next.js或数据结构不同。")
        return None

    try:
        json_data_str = script_tag.get_text()
        json_data = json.loads(json_data_str)

        agent_data = json_data['props']['pageProps']['agentData']
        name = agent_data.get('name', {}).get('full', 'N/A')
        city = agent_data.get('location', {}).get('city', 'N/A')
        state = agent_data.get('location', {}).get('state', 'N/A')
        email = agent_data.get('email', 'N/A')
        website = agent_data.get('website', 'N/A')

        return {
            "name": name,
            "city": city,
            "state": state,
            "email": email,
            "website": website
        }
    except (json.JSONDecodeError, KeyError) as e:
        print(f"解析JSON数据或提取信息失败: {e}")
        return None

# 目标URL
target_url = 'https://www.kw.com/agent/UPA-6587385179144187908-1'
agent_info = scrape_agent_info(target_url)

if agent_info:
    print("\n--- 提取的代理商信息 ---")
    print(f"姓名: {agent_info['name']}")
    print(f"城市: {agent_info['city']}")
    print(f"州: {agent_info['state']}")
    print(f"电子邮件: {agent_info['email']}")
    print(f"网站: {agent_info['website']}")
else:
    print("未能成功提取代理商信息。")

输出示例:

--- 提取的代理商信息 ---
姓名: Heidi Abele
城市: Campbell
州: CA
电子邮件: [email protected]
网站: https://heidiabelerealtor.com/

注意: 即使通过JSON成功提取了电子邮件字段,它仍然可能包含Cloudflare的电子邮件保护标记(例如[email protected]),因为这是网站在渲染时就带有的。在某些情况下,如果需要解析出真实的电子邮件地址,可能需要进一步处理这个带有data-cfemail属性的标签,或者在实际的浏览器环境中通过JavaScript执行解码逻辑。不过,对于本教程中的示例,[email protected]已经表明我们成功定位到了电子邮件信息。

注意事项与总结

  1. 网站结构多样性: 并非所有网站都使用__NEXT_DATA__。其他常见的模式包括window.__INITIAL_STATE__、script type="application/ld+json"(JSON-LD)或通过API调用获取数据。在遇到抓取困难时,使用浏览器开发者工具(F12)检查“网络(Network)”标签页,查看页面加载时发出的API请求,通常能发现数据的真正来源。
  2. JSON路径探索: 提取JSON数据后的关键是理解其结构。这通常需要打印出整个json_data字典,然后逐步深入,或者使用在线JSON格式化工具来可视化其层级。
  3. 错误处理: 在实际应用中,务必添加健壮的错误处理机制(如try-except块),以应对网络请求失败、JSON解析错误或JSON结构变化等情况。使用.get()方法访问字典键时提供默认值(如agent_data.get('name', {}).get('full', 'N/A'))可以防止KeyError,使代码更加健壮。
  4. 动态渲染: 对于完全由JavaScript在客户端渲染的网站,requests和BeautifulSoup可能不足以获取所有内容。此时,可能需要使用Selenium或Playwright等工具来模拟浏览器行为,执行JavaScript并等待内容加载。
  5. 道德与法律: 在进行网页抓取时,请务必遵守网站的robots.txt文件规定,并尊重网站的使用条款。避免对网站造成过大负担,实行适当的请求间隔和频率限制。

通过本教程,我们学习了如何超越简单的HTML解析,利用页面中嵌入的JSON数据来有效地抓取那些通过动态方式或混淆技术呈现的信息。这种方法对于处理现代Web应用中的复杂数据提取场景至关重要。

相关专题

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

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

758

2023.06.15

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

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

639

2023.07.20

python能做什么
python能做什么

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

761

2023.07.25

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

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

618

2023.07.31

python教程
python教程

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

1265

2023.08.03

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

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

548

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相关的文章、下载、课程内容,供大家免费下载体验。

708

2023.08.11

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

43

2026.01.16

热门下载

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

精品课程

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

共14课时 | 0.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

CSS教程
CSS教程

共754课时 | 19.9万人学习

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

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