如何使用BeautifulSoup4和requests库获取药品详情页的具体内容
药品详情页爬取实现方案
你原有的代码仅提取了列表页的药品标题,要获取详情页内容,首先需要从列表页提取每个药品对应的详情页路径,拼接为完整可访问的URL后逐个请求解析即可,具体实现如下:
实现步骤
- 第一步:修改列表页提取逻辑,同时获取药品标题和详情页相对路径,和站点域名拼接为完整访问URL
- 第二步:遍历所有详情页URL,发送请求后用BeautifulSoup解析页面结构,提取需要的字段(比如药品通用名、适应症、用法用量、禁忌等)
- 第三步:添加请求间隔,避免触发站点反爬机制
完整实现代码
import requests from bs4 import BeautifulSoup import time from pprint import pprint headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0' } # 站点根域名,用于拼接相对路径 BASE_URL = 'https://www.klikdokter.com' def get_drug_detail(detail_url): """获取单个药品详情页的指定字段内容""" r = requests.get(detail_url, headers=headers) r.encoding = r.apparent_encoding soup = BeautifulSoup(r.text, 'lxml') drug_info = {} # 药品全称 drug_info['title'] = soup.select_one('h1[class*=title]').text.strip() if soup.select_one('h1[class*=title]') else '' # 药品通用名 drug_info['generic_name'] = soup.select_one('div[class*=product__generic]').text.strip() if soup.select_one('div[class*=product__generic]') else '' # 药品基础描述 drug_info['description'] = soup.select_one('div[class*=product__overview]').text.strip() if soup.select_one('div[class*=product__overview]') else '' # 适应症 indication_node = soup.find('div', string='Indikasi') if indication_node and indication_node.find_next('div'): drug_info['indication'] = indication_node.find_next('div').text.strip() # 用法用量 dosage_node = soup.find('div', string='Dosis & Cara Penggunaan') if dosage_node and dosage_node.find_next('div'): drug_info['dosage'] = dosage_node.find_next('div').text.strip() # 副作用 side_effect_node = soup.find('div', string='Efek Samping') if side_effect_node and side_effect_node.find_next('div'): drug_info['side_effect'] = side_effect_node.find_next('div').text.strip() return drug_info def main(list_url): # 先爬取列表页获取所有药品的标题和详情页链接 r = requests.get(list_url, headers=headers) soup = BeautifulSoup(r.text, 'lxml') drug_items = soup.select('a[class$=section__item-link]') all_drug_info = [] for idx, item in enumerate(drug_items, start=1): drug_title = item.text.strip() detail_full_url = BASE_URL + item.get('href', '') print(f"正在爬取第{idx}个药品:{drug_title}") # 调用详情页爬取方法 detail_info = get_drug_detail(detail_full_url) all_drug_info.append(detail_info) # 每次请求间隔1秒,降低被反爬拦截的概率 time.sleep(1) print(f"全部药品爬取完成,共获取{len(all_drug_info)}条数据,前3条示例如下:") pprint(all_drug_info[:3]) if __name__ == '__main__': main('https://www.klikdokter.com/obat')
注意事项
- 上述代码中的选择器是基于当前页面结构编写的,如果站点更新了页面布局和类名,需要对应调整选择器规则
- 可以根据自身需求增减提取的字段,只需要定位到对应DOM节点修改提取逻辑即可
- 建议不要设置过高的爬取频率,避免对站点服务造成不必要的压力
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

