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

Scrapy+BeautifulSoup爬虫报d3赋值前引用UnboundLocalError求解

报错原因

触发UnboundLocalError: local variable 'd3' referenced before assignment的根本原因是:你把d3、d1这类变量的赋值逻辑全放在了try块里,当页面不存在对应字段、try块代码抛出异常时,except分支只写了pass直接跳过赋值,后续yield读取变量时,该变量从未被声明创建,自然会报未赋值错误。

除此之外你的代码还有两个会导致数据异常的问题:

  • 每遍历到一个div.line_list_K块就执行一次yield,会把单条律师详情拆成多条缺字段的无效数据
  • 列表页提取的详情页地址是相对路径,直接发起请求可能出现域名拼接失败的问题
修复方法
  • 解析字段前先给所有要输出的字段设置默认空值,就算对应字段不存在,变量也已经被定义,不会触发未赋值错误
  • 调整yield逻辑,等整个页面所有字段解析完成后,只返回一条完整数据
  • 用response.urljoin()把提取到的相对路径补全为绝对地址,避免请求出错
修复后可运行代码
import scrapy
from scrapy.http import Request
from scrapy.crawler import CrawlerProcess
from bs4 import BeautifulSoup

class TestSpider(scrapy.Spider):
    name = 'test'
    start_urls = ['https://rejestradwokatow.pl/adwokat/list/strona/1/sta/2,3,9']
    custom_settings = {
        'CONCURRENT_REQUESTS_PER_DOMAIN': 1,
        'DOWNLOAD_DELAY': 1,
        'USER_AGENT': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'
    }

    def parse(self, response):
        soup = BeautifulSoup(response.text, 'html.parser')
        tra = soup.find_all('td', class_='icon_link')
        for links in tra:
            for link in links.find_all('a', href=True):
                # 补全相对链接为绝对地址
                comp = response.urljoin(link['href'])
                yield Request(comp, callback=self.parse_book)
    
    def parse_book(self, response):
        soup = BeautifulSoup(response.text, 'html.parser')
        # 提前初始化所有字段默认值,从根源避免未赋值错误
        data = {
            'status': '',
            'd1': '',
            'd3': '',
            'd4': '',
            'd5': ''
        }
        details = soup.find_all('div', class_='line_list_K')
        for detail in details:
            try:
                data['status'] = detail.find('span', string='Status:').findNext('div').get_text(strip=True)
            except AttributeError:
                pass
            try:
                data['d1'] = detail.find('span', string='Data wpisu w aktualnej izbie na listę adwokatów:').findNext('div').get_text(strip=True)
            except AttributeError:
                pass
            try:
                data['d3'] = detail.find('span', string='Ostatnie miejsce wpisu:').findNext('div').get_text(strip=True)
            except AttributeError:
                pass
            try:
                data['d4'] = detail.find('span', string='Stary nr wpisu:').findNext('div').get_text(strip=True)
            except AttributeError:
                pass
            try:
                data['d5'] = detail.find('span', string='Zastępca:').findNext('div').get_text(strip=True)
            except AttributeError:
                pass
        # 所有字段解析完成后只返回一条完整数据
        yield data

if __name__ == "__main__":
    process = CrawlerProcess()
    process.crawl(TestSpider)
    process.start()
优化提示
  • 把裸except:替换为except AttributeError:,只捕获标签不存在导致的属性错误,不会吞掉其他代码逻辑错误,方便后续排查问题
  • 调用get_text()时加上strip=True参数,自动去除文本前后的换行、多余空格,不需要后续单独清洗
  • Scrapy自带的CSS/XPath选择器性能远高于BeautifulSoup,后续可以直接用内置选择器解析,减少依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:57:10