Python+Selenium爬取hERGdb:无法遍历LOT_ID及元素定位问题
解决hERGdb数据爬取的遍历问题与选择器错误
你已经搞定了搜索触发和单条详情爬取的核心逻辑,现在卡在了遍历LOT_ID和选择器报错上,我来帮你一步步解决:
首先修复InvalidSelectorException错误
你之前的代码报错是因为把XPath表达式传给了find_element_by_css_selector()方法——这俩是完全不同的选择器语法,自然会抛出无效选择器的错误。你可以二选一修正:
- 改用XPath方法:
driver.find_element_by_xpath('//*[@id="foo-table"]/tbody/tr[1]/td[3]/a') - 改用等价的CSS选择器:
driver.find_element_by_css_selector('#foo-table tbody tr:nth-child(1) td:nth-child(3) a')
实现LOT_ID的遍历爬取(处理分页限制)
先提前说明:hERGdb虽然显示总数据超30万,但实际上只公开展示前1000条数据(每页10条,共100页),所以我们只能爬取这部分公开可访问的数据。下面是整合后的完整代码,包含分页遍历、详情爬取和数据保存:
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoSuchElementException import pandas as pd import time # 初始化浏览器与等待器 driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver') wait = WebDriverWait(driver, 10) # 设置10秒元素加载超时 base_url = 'https://drugdesign.riken.jp/hERGdb/' driver.get(base_url) # 触发搜索操作(等待元素可点击后再操作) search_btn = wait.until(EC.element_to_be_clickable((By.NAME, 'Structure_Search'))) search_btn.click() time.sleep(2) # 等待搜索结果页面加载 # 准备存储所有爬取数据的列表 all_compound_data = [] page_num = 1 while True: print(f"正在爬取第 {page_num} 页数据...") # 等待结果表格加载完成 wait.until(EC.presence_of_element_located((By.ID, 'foo-table'))) # 获取当前页所有LOT_ID的链接元素 lot_links = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#foo-table tbody tr td:nth-child(3) a'))) # 遍历当前页的每个LOT_ID链接 for link in lot_links: hgid = link.text.strip() # 点击进入详情页 link.click() time.sleep(1) # 爬取详情页数据 compound_info = {} try: # 基础化合物信息 compound_info['HGID'] = wait.until(EC.presence_of_element_located((By.XPATH, '//tbody/tr/th[contains(.,"HGID")]/following::td[1]'))).text.strip() compound_info['Drug_name'] = wait.until(EC.presence_of_element_located((By.XPATH, '//tbody/tr/th[contains(.,"Drug_name")]/following::td[1]'))).text.strip() compound_info['MW'] = wait.until(EC.presence_of_element_located((By.XPATH, '//tbody/tr/th[contains(.,"MW")]/following::td[1]'))).text.strip() compound_info['Formula'] = wait.until(EC.presence_of_element_located((By.XPATH, '//tbody/tr/th[contains(.,"Formula")]/following::td[1]'))).text.strip() # ID关联表数据(直接提取文本,也可根据需求拆分字段) id_table_text = wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[2]/div/div/div[2]/table[2]/tbody'))).text.strip() compound_info['ID_Relation'] = id_table_text # 体外实验数据 assay_table_text = wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[2]/div/div/div[2]/table[3]/tbody'))).text.strip() compound_info['In_Vitro_Assay'] = assay_table_text all_compound_data.append(compound_info) except Exception as e: print(f"爬取HGID {hgid} 时出错: {str(e)}") # 返回列表页并等待加载 driver.back() wait.until(EC.presence_of_element_located((By.ID, 'foo-table'))) time.sleep(1) # 尝试点击下一页 try: next_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'li.next a'))) next_btn.click() page_num += 1 time.sleep(2) except NoSuchElementException: print("已爬取完所有可展示页面(共100页,1000条数据)") break # 将数据保存为CSV文件 df = pd.DataFrame(all_compound_data) df.to_csv('hERGdb_compounds.csv', index=False, encoding='utf-8-sig') print(f"爬取完成,共获取 {len(all_compound_data)} 条数据,已保存到hERGdb_compounds.csv") # 关闭浏览器 driver.quit()
额外注意事项
- 数据限制说明:hERGdb仅公开前1000条数据,后续30万+数据无法通过前端分页访问,若需要完整数据集,建议联系网站管理员申请API或数据导出权限。
- 反爬规避:代码中加入了
time.sleep()和WebDriverWait来模拟人类操作节奏,你可以根据页面实际加载速度调整等待时长。 - 错误容错:加入了基础异常捕获,避免单个条目爬取失败导致整个程序崩溃,你可以根据需求扩展错误处理逻辑。
内容的提问来源于stack exchange,提问作者Slowat_Kela
相关产品推荐
相关产品推荐

