大家好,我是何三,80后老猿,独立开发者

一、Scrapy四大「夺命」报错

1. ImportError: cannot import name '...'(经典导入陷阱)

# 错误场景
from myproject.pipelines import MysqlPipeline  # ❌报错

''' 报错信息:
ImportError: cannot import name 'MysqlPipeline' from 'myproject.pipelines'
'''

根本原因

  • 文件循环导入(A.py导入B.py,B.py又导入A.py)
  • 类未正确定义或未继承scrapy.Item/Spider

修复代码

# 正确写法(检查项目结构)
myproject/
├── __init__.py
├── pipelines.py
└── items.py

# pipelines.py中必须正确定义类
class MysqlPipeline(object):
    def process_item(self, item, spider):
        pass

2. TypeError: 'NoneType' object is not iterable(爬虫空数据崩溃)

# 错误代码
def parse(self, response):
    item = {}
    yield item  # ❌当item为空时崩溃

解决方案

# 方法1:添加空值判断
if item:  
    yield item

# 方法2:使用scrapy内置ItemLoader
from scrapy.loader import ItemLoader
loader = ItemLoader(item=MyItem(), response=response)
loader.add_xpath('name', '//h1/text()')
yield loader.load_item()

3. Twisted错误:ReactorNotRestartable(爬虫二次运行崩溃)

# 错误操作
from scrapy.crawler import CrawlerProcess
process = CrawlerProcess()
process.crawl(MySpider)
process.start()  # 第一次运行正常
process.start()  # ❌第二次报错

技术原理

Twisted的reactor不能重复启动,需要重新实例化

终极方案

# 封装成可重复调用的函数
def run_spider():
    from twisted.internet import reactor
    if reactor.running:
        reactor.stop()
    process = CrawlerProcess()
    process.crawl(MySpider)
    process.start()

4. 反爬必杀技:Forbidden by robots.txt(爬虫被拦截)

# 错误日志
[scrapy.utils.log] INFO: Ignoring response <403 http://xxx/robots.txt>

绕过方案

# settings.py中关闭robots协议
ROBOTSTXT_OBEY = False  

# 更专业的做法(模拟浏览器)
DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
    'scrapy_user_agents.middlewares.RandomUserAgentMiddleware': 400,
}

二、Flask四大「诡异」报错

5. 404 Not Found(路由黑洞)

@app.route('/user')  # ❌
def user_profile():
    return render_template('user.html')  

# 访问 /user/ 带斜杠时报错

本质原因

Flask严格区分URL末尾斜杠

根治方法

@app.route('/user/')  # ✅ 统一用斜杠结尾
def user_profile():
    return render_template('user.html')

6. TemplateNotFound(模板消失术)

# 错误提示
jinja2.exceptions.TemplateNotFound: index.html

文件结构要求

project/
├── app.py
└── templates/  # ✅ 必须这个名称
    └── index.html

配置技巧

app = Flask(__name__, template_folder='../templates')  # 自定义路径

7. RuntimeError: Working outside of application context(上下文错乱)

# 错误示例
from flask import current_app
print(current_app.config['SECRET_KEY'])  # ❌非请求上下文调用

正确打开方式

with app.app_context():  # ✅ 手动推送上下文
    print(current_app.config['SECRET_KEY'])

8. SQLAlchemy的DetachedInstanceError(数据库幽灵数据)

# 错误场景
user = User.query.get(1)
db.session.close()
print(user.name)  # ❌报错:DetachedInstanceError

ORM机制解析

Session关闭后对象处于分离状态

三种解决方案

# 方法1:重新绑定会话
db.session.add(user)

# 方法2:查询时提前加载
user = User.query.options(db.joinedload('*')).get(1)

# 方法3:使用expire_on_commit=False
app.config['SQLALCHEMY_EXPIRE_ON_COMMIT'] = False