先看代码运行结果,为方便测试、减少循环次数,只爬取了心血管内科A、B开头的六种疾病数据。
总体思路
“查疾病”这部分内容按科室分类,各个科室网站不同。在最初尝试中,我使用 requests 库获取网页内容,但发现获取到的 HTML 源码与我在网站上通过开发者模式查看到的代码不一致。经过 GPT 解释,网站采用 JavaScript 进行动态加载内容,而我所获取的仅仅是初始加载时的 HTML 源码,不包含通过 JavaScript 动态生成的内容。
因此,我转向使用 Selenium 模拟浏览器行为。这也为我解决在网页不发生跳转的情况下,如何获取每个首字母下的疾病列表提供了思路。
为了获取每个科室下按疾病首字母分类的疾病列表,我编写了程序自动点击每个字母按钮,获取相应的动态源码。随后,我通过循环对这些源码进行解析,提取了详细介绍每个疾病的网站跳转链接。
最后的工作就是对每个疾病页面进行解析,获取了相关的疾病信息。
函数说明
-
get_static_url_content_after_click(driver, url, button_text)
- 作用:使用 Selenium WebDriver 模拟点击操作后获取静态网页内容。
- 参数:
driver
: WebDriver对象,用于控制浏览器。url
: 要打开的网页URL。button_text
: 页面中的按钮文本。
- 返回:BeautifulSoup对象,包含解析后的页面内容。
-
start_crawler(subject)
- 作用:开始爬取特定科室的链接。
- 参数:
subject
: 科室的编号或名称。
- 返回:包含科室链接列表的列表。
-
get_static_url_content(url)
- 作用:使用 Selenium WebDriver 获取指定 URL 的静态网页内容。
- 参数:
url
(str): 要获取内容的网页链接。
- 返回:BeautifulSoup对象,用于解析HTML。
-
get_disease_info(url)
- 作用:获取特定疾病的详细信息。
- 参数:
url
: 疾病页面的链接。
- 返回:包含疾病信息的字典或其他数据结构。
-
write_to_file(file_name, content)
- 作用:将内容写入指定的文件(追加模式)。
- 参数:
file_name
(str): 要写入的文件的名称。content
(dict): 要写入文件的内容,这里假设是一个字典。
- 返回:无。
main函数调用逻辑
- 创建一个映射字典
subject_mapping
用于科室编号和名称的映射。 - 创建一个字典
all_subject_links
用于存储每个科室的疾病链接。 - 针对每个科室,调用
start_crawler
函数获取疾病链接,并存储在all_subject_links
字典中。 - 对于每个科室,循环遍历其链接,然后对每个链接调用
get_disease_info
函数获取疾病信息,最后调用write_to_file
函数将疾病信息以 JSON 格式写入文件中。
代码
from bs4 import BeautifulSoup
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import json
def get_static_url_content_after_click(driver, url, button_text):
"""
使用 Selenium WebDriver 模拟点击操作后获取静态网页内容。
Parameters:
- driver: WebDriver对象,用于控制浏览器
- url: 要打开的网页URL
- button_text: 页面中的按钮文本
Returns:
- bsObj: BeautifulSoup对象,包含解析后的页面内容
"""
# 打开网页
driver.get(url)
# 使用 WebDriverWait 等待页面元素加载
button = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH,
f"//div[@class='tag-button' and text()='{
button_text