
本教程深入探讨了在使用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}")这段代码能够成功提取姓名、位置和网站链接。然而,如果尝试以类似的方式提取电子邮件地址,例如通过查找一个带有特定类名的<a>标签,结果可能会是这样的:
/cdn-cgi/l/email-protection#f18394909d94828590859482b199949895989093949d94df929e9c
这显然不是一个可用的电子邮件地址,而是一个由CDN服务(如Cloudflare)提供的电子邮件保护机制。这意味着真实的电子邮件地址并没有直接以明文形式存在于我们通过requests.get()获取的HTML中。
当直接解析HTML元素无法获取所需数据时,一个有效的策略是检查页面中是否包含以JSON格式嵌入的数据。许多现代的JavaScript框架(如Next.js、React等)在服务器端渲染(SSR)或静态生成(SSG)时,会将页面所需的数据预加载到一个特殊的<script>标签中,通常其ID为__NEXT_DATA__或类似的标识符。这些数据通常以JSON字符串的形式存储,并且包含了页面渲染所需的所有信息,包括那些被混淆或动态生成的数据。
首先,我们需要使用BeautifulSoup找到包含JSON数据的<script>标签。对于使用Next.js构建的网站,这个标签通常具有id="__NEXT_DATA__"。
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字符串解析为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 电子邮件: <a class="__cf_email__" data-cfemail="ec9e898d80899f988d98899fac84898588858d8e898089c28f8381" href="/cdn-cgi/l/email-protection">[email protected]</a> 网站: https://heidiabelerealtor.com/
注意: 即使通过JSON成功提取了电子邮件字段,它仍然可能包含Cloudflare的电子邮件保护标记(例如[email protected]),因为这是网站在渲染时就带有的。在某些情况下,如果需要解析出真实的电子邮件地址,可能需要进一步处理这个带有data-cfemail属性的<a>标签,或者在实际的浏览器环境中通过JavaScript执行解码逻辑。不过,对于本教程中的示例,[email protected]已经表明我们成功定位到了电子邮件信息。
通过本教程,我们学习了如何超越简单的HTML解析,利用页面中嵌入的JSON数据来有效地抓取那些通过动态方式或混淆技术呈现的信息。这种方法对于处理现代Web应用中的复杂数据提取场景至关重要。
以上就是使用Requests和BeautifulSoup解析动态内容与处理邮件混淆技术的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号