如何使用Selenium Python实现网站解析、新标签页打开与数据爬取
Selenium Python 高校社团批量爬取优化实现
核心优化点
- 优先抓取全量社团详情页URL,避免页面跳转后元素引用失效
- 采用新标签页独立爬取每个社团数据,爬取完成后自动关闭标签页切回列表页,无需重复加载列表页
- 替换硬编码等待为显式等待,降低爬取耗时、减少元素未加载报错
- 封装单页爬取逻辑,消除重复代码,新增异常捕获,避免单个社团数据异常导致全量任务失败
- 兼容Selenium 4+ 官方推荐写法,替换已废弃的
find_element_by_*接口 - 新增空值兼容逻辑,避免不同社团字段不一致导致数据存储失败
优化后完整代码
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import pandas as pd import time import random # 配置chromedriver路径,也可以用webdriver-manager自动管理,无需手动指定路径 chrome_service = Service("C:/Users/EMRE/Desktop/chromedriver_win32/chromedriver.exe") browser = webdriver.Chrome(service=chrome_service) wait = WebDriverWait(browser, 10) # 最长等待10秒,元素加载完成就继续执行 # 打开社团列表页 browser.get("http://event.ybu.edu.tr/kulupler/") time.sleep(2) # 第一步:先抓取所有社团的详情页URL club_urls = [] club_items = wait.until(EC.presence_of_all_elements_located((By.XPATH, "/html/body/div[2]/div[2]/div/a"))) for item in club_items: club_url = item.get_attribute("href") club_urls.append(club_url) print(f"共抓取到{len(club_urls)}个社团链接") # 存储全量数据的列表 all_data = [] # 第二步:遍历每个社团链接,开新标签页爬取 main_window = browser.current_window_handle # 保存列表页的句柄,方便切回 for url in club_urls: # 新开标签页打开社团详情 browser.execute_script("window.open(arguments[0]);", url) # 切换到新标签页 for window in browser.window_handles: if window != main_window: browser.switch_to.window(window) break club_info = {} try: # 等待详情页基础内容加载完成 wait.until(EC.presence_of_element_located((By.ID, "bilgiler"))) # 爬取社团名称 club_info["社团名称"] = browser.find_element(By.XPATH, '//*[@id="bilgiler"]/table/tbody/tr[1]/td[2]').text.strip() # 爬取邮箱 mail_ele = browser.find_elements(By.CSS_SELECTOR, "#bilgiler > a.btn.bg-orange.btn-social") club_info["邮箱地址"] = mail_ele[0].text.strip() if mail_ele else "" # 爬取Facebook fb_ele = browser.find_elements(By.CSS_SELECTOR, "#bilgiler > a.btn.bg-blue.btn-social") club_info["Facebook地址"] = fb_ele[0].text.strip() if fb_ele else "" # 爬取Twitter tw_ele = browser.find_elements(By.CSS_SELECTOR, "#bilgiler > a.btn.btn-social.bg-aqua") club_info["Twitter地址"] = tw_ele[0].text.strip() if tw_ele else "" # 爬取Instagram ins_ele = browser.find_elements(By.CSS_SELECTOR, "#bilgiler > a.btn.btn-social.bg-light-blue") club_info["Instagram地址"] = ins_ele[0].text.strip() if ins_ele else "" # 爬取学术顾问 club_info["学术顾问"] = browser.find_element(By.XPATH, '//*[@id="bilgiler"]/table/tbody/tr[2]/td[2]').text.strip() # 爬取社团主席 club_info["社团主席"] = browser.find_element(By.XPATH, '//*[@id="bilgiler"]/table/tbody/tr[3]/td[2]').text.strip() # 爬取总会员数 club_info["总会员数"] = browser.find_element(By.XPATH, '//*[@id="bilgiler"]/table/tbody/tr[4]/td[2]').text.strip() # 爬取总活动数 club_info["总活动数"] = browser.find_element(By.XPATH, '//*[@id="bilgiler"]/table/tbody/tr[5]/td[2]').text.strip() all_data.append(club_info) print(f"已完成爬取:{club_info['社团名称']}") except Exception as e: print(f"爬取链接{url}出错,错误信息:{str(e)}") finally: # 关闭当前详情页标签 browser.close() # 切回列表页标签 browser.switch_to.window(main_window) # 随机延迟1-3秒,避免触发反爬限制 time.sleep(random.randint(1,3)) # 导出数据到csv df = pd.DataFrame(all_data) df.to_csv("AYBU全量社团数据.csv", index=False, encoding="utf-8-sig") print(f"共成功爬取{len(all_data)}条社团数据,已导出到文件") # 关闭浏览器 browser.quit()
可选优化补充
如果不想手动配置chromedriver路径,可以安装webdriver-manager库,替换driver初始化代码即可自动适配当前Chrome版本:
from webdriver_manager.chrome import ChromeDriverManager browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
内容的提问来源于stack exchange,提问作者codesfullinmymind
相关产品推荐
相关产品推荐

