Scrapy结合Selenium点击元素报Selector无法JSON序列化错误如何解决
错误原因
你的报错本质是类型不匹配:
- 你通过
response_obj.xpath拿到的link是Scrapy框架的Selector对象,仅用于内容解析,不是Selenium可以识别的浏览器原生WebElement对象 - 调用
driver.execute_script执行点击时,Selenium会尝试把传入的参数转成浏览器可识别的格式,Selector对象无法完成序列化,就会抛出这个错误
另外你现存的代码还有两处逻辑错误:
- 你的xpath选择的是id为
tableRepeat2的tbody元素本身,不是tbody下可点击的行元素,就算类型对了也没法批量点击 - 提取
Ocupatia字段时直接返回了Selector对象,没有调用提取方法,就算点击成功保存数据时也会报错
修复方案
核心修改逻辑是:要点击的元素直接用Selenium的API从浏览器实例中获取,不要用Scrapy的Selector获取;提取内容时加等待逻辑,提取完成后调用方法拿到实际字符串。
修复后的完整代码如下:
# -*- coding: utf-8 -*- import scrapy from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from scrapy.selector import Selector from scrapy_selenium import SeleniumRequest class AnofmSpider(scrapy.Spider): name = 'anofm' def start_requests(self): yield SeleniumRequest( url='https://www.anofm.ro/lmvw.html?agentie=Covasna&categ=3&subcateg=1', callback=self.parse ) def parse(self, response): driver = response.meta['driver'] # 等待列表加载完成 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "tableRepeat2")) ) # 直接用Selenium获取所有可点击的行元素,xpath可根据实际页面可点击元素调整 clickable_rows = driver.find_elements(By.XPATH, "//tbody[@id='tableRepeat2']/tr") for idx in range(len(clickable_rows)): # 每次循环重新获取元素,避免点击后后退导致元素失效 current_row = driver.find_elements(By.XPATH, "//tbody[@id='tableRepeat2']/tr")[idx] # 执行点击 driver.execute_script("arguments[0].click();", current_row) # 等待详情内容加载完成 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "print")) ) # 提取内容,调用.get()拿到实际字符串 yield { 'Ocupatia': Selector(text=driver.page_source).xpath("//div[@id='print']/p/text()[1]").get() } # 点击后返回列表页,准备点下一个元素,可根据实际页面调整后退逻辑 driver.back() # 等待列表重新加载 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "tableRepeat2")) )
内容的提问来源于stack exchange,提问作者Jonathan Simpson
相关产品推荐
相关产品推荐

