大家好,我是何三,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