一般在写一个项目的时候, 为了将项目模块化, 更加的清晰明了, 会将不同功能的模块放入不同的文件夹
项目如下:
├── spider
│ └── spider.py # 爬虫文件
└── utils
├── __init__.py
└── downloads.py # 下载模块
downloads.py内容如下:
def download():
print("import download")
spider.py内容如下:
from ..utils.downloads import download
download()
一切看起来都是那么美好
当你试图运行
问题一出现:
cd spider
python3 spider.py
会得到:
# 相对导入超出顶级包错误
Traceback (most recent call last):
File "spider.py", line 7, in <module>
from ..utils.downloads import download
ValueError: attempted relative import beyond top-level package
但是你试图把相对路径去掉时, 又会得到:
# 找不到这个模块
ModuleNotFoundError: No module named 'utils'
尝试解决:
在spider.py文件第一行加入:
import sys
sys.path.append("../")
输出:
> import download
问题二:
mgd, 终于解决了,
but, 一般爬虫脚本, 要用crontab或其他定时调用脚本时, 要使用绝对路径
在根目录或家目录下试一下:
python3 /Users/msw/Desktop/wx_post/py_module/spider/spider.py
结果, 不出意外, 咦~~~~~~~
Traceback (most recent call last):
File "/Users/msw/Desktop/wx_post/py_module/spider/spider.py", line 9, in <module>
from utils.downloads import download
ModuleNotFoundError: No module named 'utils'
于是:
在spider.py再加入一行
sys.path.append("/Users/msw/Desktop/wx_post/py_module/")
在运行一下:
> import download
果然可以了, 但是不能把所有的路径都添加一边吧, 大神到这步应该就知道怎么解决了吧
解决:
其实, 说来说去, 根本问题就是脚本工作目录的问题, 也就是在那里启用的脚本
方案一:
改变目录结构, 内容保持一致, 如下:
├── spider.py
└── utils
├── __init__.py
└── downloads.py
spider.py, 内容如下:
from utils.downloads import download
download()
方案二:
目录结构保持不变
在spider/spider.py, 开始处加上以下内容:
import os
import sys
work_dir, file_name = os.path.split(__file__)
os.chdir(work_dir if work_dir else "./")
sys.path.append("../")
其实就是改变了, 脚本工作目录