
在进行网页数据抓取(web scraping)时,开发者经常会遇到一个普遍的问题:网页上的不同类型的信息可能被包裹在具有相同html类名(class name)的标签中。例如,一个医生可能有多个执业地点,包括实体医院和在线咨询服务,而这些地点信息可能都使用相同的<div>标签和class属性。如果我们的目标是仅获取实体医院的地点信息,而排除在线咨询,就需要一种有效的方法来区分和筛选这些数据。
要解决上述问题,我们将使用Python中两个强大的库:
在开始之前,请确保已安装这些库:
pip install requests beautifulsoup4
假设我们正在抓取医生信息,每个医生可能在多个地点提供服务。这些地点(无论是实体医院还是在线咨询)都可能使用相同的CSS类名(例如listing-locations)。我们的目标是只获取医生提供的实体医院服务地点,并忽略任何“在线视频咨询”的地点。
解决此问题的关键在于利用BeautifulSoup提供的强大CSS选择器功能,特别是:-soup-contains()伪类选择器,它允许我们根据元素内包含的文本内容进行筛选。
立即学习“Python免费学习笔记(深入)”;
首先,我们需要使用requests库获取目标网页的HTML内容。
import requests from bs4 import BeautifulSoup url = "https://oladoc.com/pakistan/lahore/gynecologist" # 发送GET请求并获取响应 response = requests.get(url) # 检查请求是否成功 response.raise_for_status() # 使用BeautifulSoup解析HTML内容 soup = BeautifulSoup(response.content, "html.parser")
通常,网页上的每个独立信息块(例如,每个医生的完整信息)都会被一个特定的HTML元素包裹。我们需要找到这些主要的容器。根据示例,每个医生的信息都包含在class="gynecologist"的元素中。
# 遍历所有医生信息块
for g in soup.select(".gynecologist"):
# 提取医生姓名
doctor_name = g.h2.get_text(strip=True)
print("姓名:", doctor_name)
# ... 接下来是提取地点信息这是解决问题的核心步骤。我们需要选择所有具有listing-locations类的元素,但同时排除那些文本内容包含“Online Video Consultation”的元素。BeautifulSoup的select()方法支持复杂的CSS选择器,包括:-soup-contains()。
结合起来,".listing-locations:not(:-soup-contains('Online Video Consultation'))"将选择所有class为listing-locations,但不包含“Online Video Consultation”文本的元素。
# 筛选医院地点:选择所有class为listing-locations,且不包含“Online Video Consultation”文本的元素
hospitals = g.select(
".listing-locations:not(:-soup-contains('Online Video Consultation'))"
)
# 提取每个筛选出的医院名称
hospital_names = [h.span.text.strip() for h in hospitals]
print("医院:", hospital_names)
print("-" * 30) # 分隔线,使输出更清晰将以上步骤整合,得到完整的Python抓取脚本:
import requests
from bs4 import BeautifulSoup
# 目标URL
url = "https://oladoc.com/pakistan/lahore/gynecologist"
try:
# 发送GET请求并获取网页内容
response = requests.get(url)
response.raise_for_status() # 检查请求是否成功,如果状态码不是200,则抛出异常
# 使用BeautifulSoup解析HTML
soup = BeautifulSoup(response.content, "html.parser")
# 遍历页面上所有的医生信息块
for g in soup.select(".gynecologist"):
# 提取医生姓名
doctor_name = g.h2.get_text(strip=True)
print("姓名:", doctor_name)
# 筛选医院地点:
# 选择所有class为"listing-locations"的元素,
# 但排除那些内部文本包含"Online Video Consultation"的元素。
hospitals = g.select(
".listing-locations:not(:-soup-contains('Online Video Consultation'))"
)
# 提取每个筛选出的医院名称,并去除首尾空白
hospital_names = [h.span.text.strip() for h in hospitals]
print("医院:", hospital_names)
print("-" * 40) # 打印分隔线
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
except Exception as e:
print(f"发生错误: {e}")
输出示例:
姓名: Dr. Ayesha Azam Khan 医院: ['National Hospital & Medical Centre (DHA)', 'Surgimed Hospital (Gulberg)'] ---------------------------------------- 姓名: Dr. Maliha Amjad 医院: ['Omar Hospital & Cardiac Centre (Johar Town) (Johar Town)', 'Shalamar Hospital (Mughalpura)'] ---------------------------------------- 姓名: Dr. Sara Rasul 医院: ['Hameed Latif Hospital (New Garden Town)', 'Hameed Latif Medical Center (DHA)'] ---------------------------------------- # ... 更多医生信息
通过本教程,我们学习了如何利用Python的requests和BeautifulSoup库,结合强大的CSS选择器(特别是:-soup-contains()和:not()),有效地处理网页抓取中同名类标签的挑战。这种方法不仅能够精确地筛选出所需数据,还能排除不必要或干扰性的信息,从而提高数据抓取的准确性和效率。掌握这些技巧,将使您在面对复杂网页结构时更加游刃有余。
以上就是Python Web Scraping技巧:处理同名类标签并精确筛选数据的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号