You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Scrapy结合Selenium爬取动态加载内容及Excel URL入库技术问询

我明白你现在的困境——动态加载内容确实是爬虫的常见痛点,尤其是Scrapy默认没法处理JS渲染的内容,Splash有时候也会因为页面渲染机制的问题失效。咱们先从Selenium的正确实现开始,然后再聊聊其他可行的方案。

一、Selenium 获取动态文本的可行示例

首先要纠正你当前代码里的小问题:你同时初始化了独立的driver实例和使用SeleniumRequest,这会导致资源冲突。下面分两种场景给出可行代码:

1. 纯Selenium独立爬取示例(适合调试验证)

这个示例优先直接获取页面渲染后的文本,比截图OCR高效得多,还能处理懒加载内容:

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
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import time
from webdriver_manager.chrome import ChromeDriverManager

def scrape_dynamic_content(url):
    # 自动管理ChromeDriver,无需手动配置路径
    driver = webdriver.Chrome(ChromeDriverManager().install())
    
    try:
        driver.get(url)
        # 等待页面核心动态元素加载完成(替换成目标页面的实际元素选择器)
        wait = WebDriverWait(driver, 15)
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".product-listing")))
        
        # 滚动页面处理懒加载,确保所有内容加载完毕
        last_height = driver.execute_script("return document.body.scrollHeight")
        while True:
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            time.sleep(2)
            new_height = driver.execute_script("return document.body.scrollHeight")
            if new_height == last_height:
                break
            last_height = new_height
        
        # 获取页面文本(可选择整页或指定元素)
        # 方式1:获取整个页面文本
        page_text = driver.find_element(By.TAG_NAME, "body").text
        # 方式2:获取指定区块文本(更精准)
        # page_text = driver.find_element(By.CSS_SELECTOR, ".product-listing").text
        
        return page_text
    
    except TimeoutException:
        print(f"页面加载超时:{url}")
    except NoSuchElementException:
        print(f"未找到目标元素:{url}")
    finally:
        driver.quit()

# 测试调用
scrape_dynamic_content("https://www.analog.com/en/products/landing-pages/new-products-listing.html")

2. Scrapy集成Selenium的正确写法

如果要在Scrapy框架里使用,建议依托scrapy-selenium的内置Driver管理,不要自己初始化Driver:

import scrapy
from scrapy_selenium import SeleniumRequest
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

class QuotesSpider(scrapy.Spider):
    name = "quotes"

    def start_requests(self):
        urls = [
            'https://www.analog.com/en/products/landing-pages/new-products-listing.html',
        ]
        for url in urls:
            yield SeleniumRequest(
                url=url,
                callback=self.parse,
                wait_time=15,
                # 等待目标元素加载完成后再回调
                wait_until=EC.presence_of_element_located((By.CSS_SELECTOR, ".product-listing")),
                # 滚动页面触发懒加载
                script='window.scrollTo(0, document.body.scrollHeight);'
            )

    def parse(self, response):
        # 从response元数据中获取Selenium Driver实例
        driver = response.meta['driver']
        # 获取页面文本
        page_text = driver.find_element(By.TAG_NAME, "body").text
        
        # 后续可将page_text写入数据库,这里先返回示例数据
        yield {
            'url': response.url,
            'content': page_text[:500]  # 只返回前500字符示例
        }
二、其他可行方案

如果Selenium还是不顺畅,试试这些替代思路:

  • 方案1:直接爬取后端API接口
    很多动态内容是通过XHR/Fetch请求从后端API获取的。打开浏览器开发者工具(F12),切换到Network标签筛选XHR请求,找到返回目标内容的API接口,直接用Scrapy请求这些接口——这种方式比渲染整个页面高效10倍以上,还能拿到结构化的JSON数据。

  • 方案2:用Playwright替代Selenium
    Playwright是微软推出的自动化工具,对现代前端框架(React/Vue)的支持更好,内置智能等待机制,代码更简洁:

from playwright.sync_api import sync_playwright

def scrape_with_playwright(url):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()
        page.goto(url)
        # 等待页面网络空闲(所有请求完成)
        page.wait_for_load_state("networkidle")
        # 滚动页面触发懒加载
        page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
        page.wait_for_timeout(2000)
        # 获取文本内容
        page_text = page.locator("body").text_content()
        browser.close()
        return page_text
  • 方案3:万不得已时用OCR提取文本
    如果页面内容确实是图片形式(比如图片化的产品说明),再考虑OCR。需要安装pytesseractPillow
from selenium import webdriver
from PIL import Image
import pytesseract

# Windows系统需指定Tesseract路径,Mac/Linux可忽略
# pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

def scrape_with_ocr(url):
    driver = webdriver.Chrome()
    driver.get(url)
    # 截取整页截图
    driver.save_screenshot("page_screenshot.png")
    # 识别图片文本
    img = Image.open("page_screenshot.png")
    text = pytesseract.image_to_string(img)
    driver.quit()
    return text

注意:OCR准确率受图片清晰度、字体影响较大,不到万不得已不推荐使用。

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

火山引擎 最新活动