You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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()  # 修正:用正确的驱动变量名退出浏览器

关键修改说明

  1. 导入json模块:这是写入JSON文件的基础,没有它json.dump()无法运行。
  2. 优化循环逻辑:改用try-except结合WebDriverWait,等待按钮可点击,避免因页面加载慢导致的点击失败,同时当按钮消失时自动退出循环,比原有的判断更可靠。
  3. 增加元素容错:在获取标题和链接时,先判断元素是否存在,避免单个元素缺失导致整个脚本崩溃。
  4. 格式化JSON输出:添加indent=2参数,让生成的JSON文件结构和你预期的格式一致,可读性更强。
  5. 指定文件编码:打开文件时指定encoding='utf-8',避免中文等特殊字符出现编码乱码问题。
  6. 修正驱动退出语句:把browser.quit()改成driver.quit(),和初始化的变量名保持一致。

内容的提问来源于stack exchange,提问作者brawlins4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:46:33