使用Selenium与BeautifulSoup爬取带Load More按钮网站时JSON导出异常
解决Selenium爬取后写入JSON的问题
看起来你的脚本里有几个小问题导致JSON写入失败,我帮你梳理并修正一下:
主要问题分析
- 缺少
json模块导入:你调用了json.dump()但没导入json库,这会直接抛出NameError。 - 驱动变量名错误:最后用了
browser.quit(),但你初始化的驱动实例是driver,应该用driver.quit()。 - 冗余代码:循环里的
html = driver.page_source.encode('utf-8')没有实际作用,可以直接移除。 - 循环条件不够可靠:原循环只判断按钮是否存在,但若按钮存在却不可点击/不可见,会导致无效操作,建议优化为等待按钮可点击的逻辑。
修正后的完整代码
from bs4 import BeautifulSoup as soup 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 time import json # 新增:导入json模块 url = "https://smarthistory.org/americas-before-1900/" driver = webdriver.Chrome('/Users/rawlins/Downloads/chromedriver') driver.get(url) page_num = 0 while True: try: # 等待按钮可见并可点击,避免页面未加载完成就触发点击 load_more_btn = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.CSS_SELECTOR, '#load-more-cc-objects')) ) load_more_btn.click() page_num += 1 print(f"getting page number {page_num}") time.sleep(1) except: # 当按钮不存在或不可点击时,退出循环 print("No more pages to load") break data = [] # 解析页面HTML page_soup = soup(driver.page_source, 'lxml') containers = page_soup.findAll("div", {"class":"mb-8 hover-zoom tablescraper-selected-row opacity-100"}) for container in containers: item = {} item['type'] = "Course Material" # 增加容错:避免找不到标题元素导致脚本崩溃 title_elem = container.find('h5', {'class' : 'm-0 mt-4 text-grey-darker text-normal leading-tight hover-connect'}) item['title'] = title_elem.text.strip() if title_elem else "No Title" # 同样给链接增加容错 item['link'] = container.a["href"] if container.a else "No Link" item['source'] = "Smarthistory" item['base_url'] = "https://smarthistory.org" item['license'] = "Attribution-NonCommercial-ShareAlike" data.append(item) # 写入JSON时增加indent参数,让输出和你预期的格式一致 with open("smarthistory-2.json", "w", encoding='utf-8') as writeJSON: json.dump(data, writeJSON, ensure_ascii=False, indent=2) driver.quit() # 修正:用正确的驱动变量名退出浏览器
关键修改说明
- 导入
json模块:这是写入JSON文件的基础,没有它json.dump()无法运行。 - 优化循环逻辑:改用
try-except结合WebDriverWait,等待按钮可点击,避免因页面加载慢导致的点击失败,同时当按钮消失时自动退出循环,比原有的判断更可靠。 - 增加元素容错:在获取标题和链接时,先判断元素是否存在,避免单个元素缺失导致整个脚本崩溃。
- 格式化JSON输出:添加
indent=2参数,让生成的JSON文件结构和你预期的格式一致,可读性更强。 - 指定文件编码:打开文件时指定
encoding='utf-8',避免中文等特殊字符出现编码乱码问题。 - 修正驱动退出语句:把
browser.quit()改成driver.quit(),和初始化的变量名保持一致。
内容的提问来源于stack exchange,提问作者brawlins4
相关产品推荐
相关产品推荐

