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

无法访问派生类新方法及网页爬取存入Solr索引技术咨询

问题2:爬取网页存入Solr的代码检查与优化建议

先看你给出的代码片段,我挑几个关键问题和优化点说:

现有代码的潜在问题

crawledLinks = [] 
solr = pysolr.Solr('some url', timeout=10) 

class MySpider(Spider): 
    name = "tutsplus" 
    start_urls = ["some url"] 
    allowed_domains = ["some domain"] 
    custom_settings = { 
        'CONCURRENT_REQUESTS': 100, 
        'CONCURRENT_REQUESTS_PER_DOMAIN': 100, 
        'DEPTH_LIMIT': 100, 
        'LOG_ENABLED': True, 
    } 
    def parse(self, response): 
        links = response.xpath('//a/@href').extract() 
        current_url = response.url 
        ...
  1. 全局变量的线程安全问题:crawledLinks是全局列表,Scrapy是多线程异步框架,多个爬虫线程同时操作这个列表会导致数据混乱(比如重复添加、丢失数据)。Solr实例全局化也有问题,pysolr的连接不是线程安全的,多线程共享可能引发连接异常。
  2. 并发设置过高:CONCURRENT_REQUESTS和CONCURRENT_REQUESTS_PER_DOMAIN都设为100,这会瞬间给目标网站发大量请求,大概率会被封禁IP,甚至直接把对方服务器打崩,非常不友好。
  3. 链接处理不完整:links = response.xpath('//a/@href').extract()拿到的是相对URL,需要转换成绝对URL,而且没有去重逻辑,会导致重复爬取。
  4. 缺少异常处理:Solr的操作(比如添加文档)很容易因为网络问题、格式错误失败,但代码里没有任何异常捕获,会直接导致爬虫崩溃。
  5. 日志设置太简单:LOG_ENABLED: True只是开启日志,但没有设置日志级别和输出格式,出问题的时候很难排查。

优化后的代码示例

from scrapy.spiders import Spider
from scrapy.utils.url import urljoin
import pysolr
from scrapy.exceptions import CloseSpider
import scrapy

class MySpider(Spider):
    name = "tutsplus"
    start_urls = ["some url"]
    allowed_domains = ["some domain"]
    custom_settings = {
        'CONCURRENT_REQUESTS': 10,  # 降低并发,友好爬取
        'CONCURRENT_REQUESTS_PER_DOMAIN': 5,
        'DEPTH_LIMIT': 5,  # 深度不用设100,除非你真的需要爬这么深
        'LOG_LEVEL': 'INFO',  # 明确日志级别
        'LOG_FORMAT': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        'ROBOTSTXT_OBEY': True,  # 遵守robots协议,避免法律风险
        'DOWNLOAD_DELAY': 1,  # 增加请求间隔,降低反爬风险
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 把Solr实例放到类属性里,每个爬虫实例单独初始化
        try:
            self.solr = pysolr.Solr('some url', timeout=10)
        except Exception as e:
            self.logger.error(f"Failed to connect to Solr: {str(e)}")
            raise CloseSpider("Solr connection failed")
        # 用集合维护已爬URL,比列表查询更快
        self.crawled_urls = set()
        # 批量提交的缓存,攒够20条再提交Solr
        self.solr_batch = []
        self.batch_size = 20

    def parse(self, response):
        # 跳过已爬取的URL
        if response.url in self.crawled_urls:
            return
        self.crawled_urls.add(response.url)

        # 提取页面数据(示例:标题、内容、URL)
        item = {
            'url': response.url,
            'title': response.xpath('//title/text()').get(default=''),
            'content': ' '.join(response.xpath('//p/text()').getall()).strip()
        }

        # 加入批量缓存,达到阈值就提交
        self.solr_batch.append(item)
        if len(self.solr_batch) >= self.batch_size:
            self._submit_to_solr()

        # 处理链接:转绝对URL + 过滤允许域名 + 去重
        links = response.xpath('//a/@href').getall()
        domain_prefixes = (f'http://{self.allowed_domains[0]}', f'https://{self.allowed_domains[0]}')
        for link in links:
            absolute_url = urljoin(response.url, link)
            if absolute_url.startswith(domain_prefixes) and absolute_url not in self.crawled_urls:
                yield scrapy.Request(absolute_url, callback=self.parse)

    def _submit_to_solr(self):
        """批量提交数据到Solr的私有方法"""
        try:
            self.solr.add(self.solr_batch)
            self.logger.info(f"Successfully indexed {len(self.solr_batch)} documents")
            self.solr_batch.clear()
        except Exception as e:
            self.logger.error(f"Failed to submit batch to Solr: {str(e)}")

    def closed(self, reason):
        """爬虫关闭时提交剩余的缓存数据"""
        if self.solr_batch:
            self._submit_to_solr()

额外优化建议

  • 增量爬取策略:给每个Solr文档添加last_modified字段,爬取时对比页面的Last-Modified响应头,只更新有变化的内容,避免重复索引。
  • 数据格式验证:存入Solr前验证必填字段是否存在、格式是否符合要求(比如URL合法性、内容长度),可以用Scrapy的Item Pipeline做统一校验。
  • Solr连接池配置:如果爬虫规模较大,可以给pysolr配置连接池(比如pysolr.Solr(..., pool_kwargs={'maxconnections': 10})),提升连接复用效率。
  • 代理IP配置:如果目标网站反爬严格,可以添加Scrapy代理中间件,切换不同IP进行爬取,降低封禁风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:31:43