python--将模块名称导入为变量(动态加载传递的参数中的模块)

8 浏览
0 Comments

python--将模块名称导入为变量(动态加载传递的参数中的模块)

Python 3.4.2... 我一直在尝试从参数中动态加载一个自定义模块。我想加载自定义代码来爬取特定的HTML文件。例如:scrape.py -m 要加载的模块名 要爬取的文件.html。我尝试了很多解决方案,包括这个:当模块名存在于变量中时导入模块。当我使用实际的模块名而不是变量名args.module时,模块加载成功。代码如下:

$ cat scrape.py 
#!/usr/bin/env python3
from urllib.request import urlopen
from bs4 import BeautifulSoup
import argparse
import os, sys
import importlib
parser = argparse.ArgumentParser(description='HTML网页爬虫')
parser.add_argument('filename', help='要操作的文件')
parser.add_argument('-m', '--module', metavar='MODULE_NAME', help='包含特定于网站的代码的文件--必须是名为Scrape的定义类')
args = parser.parse_args()
if args.module:
#    from get_div_content import Scrape #这个是可以工作的#
    sys.path.append(os.getcwd())
    #修改这里:
    #错误# module_name = importlib.import_module(args.module, package='Scrape')
    #为:
    module = importlib.import_module(args.module) # 正确
try:
    html = open(args.filename, 'r')
except:
    try:
    html = urlopen(args.filename)
    except HTTPError as e:
    print(e)
try:
    soup = BeautifulSoup(html.read())
except:
    print("错误... 对不起... 不确定发生了什么")
#修改这里
#错误#scraper = Scrape(soup)
#为:
scraper = module.Scrape(soup) # 正确


模块:

$ cat get_div_content.py 
class Scrape:
    def __init__(self, soup):
    content = soup.find('div', {'id':'content'})
    print(content)


运行命令和错误:

$ ./scrape.py -m get_div_content.py file.html 
Traceback (most recent call last):
  File "./scrape.py", line 16, in 
    module_name = importlib.import_module(args.module, package='Scrape')
  File "/usr/lib/python3.4/importlib/__init__.py", line 109, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "", line 2249, in _gcd_import
  File "", line 2199, in _sanity_check
SystemError: Parent module 'Scrape' not loaded, cannot perform relative import


正常运行命令 -- 无错误:

$ ./scrape.py -m get_div_content file.html
...

0
0 Comments

问题出现的原因是因为需要根据传递的参数动态加载模块,但是在使用import_module函数时,传递的参数是一个字符串,而不是一个变量。解决方法是使用importlib库中的import_module函数,将传递的参数作为字符串传递给函数,并将返回的模块赋值给一个变量,然后可以使用该变量来访问模块中定义的内容。

具体的解决方法如下:

import importlib
# 通过传递的参数加载模块
module = importlib.import_module(args.module)
# 使用加载的模块中定义的内容
scraper = module.Scrape(soup)

需要注意的是,在调用时要使用模块的名称,而不是文件名。

./scrape.py -m get_div_content file.html

通过以上方法,问题得到了解决。感谢您的答案,现在我明白了。我已经修改了原帖以展示实际的更改。请查找`#EDIT`。

以上就是关于"python--Import module name as variable (dynamically load module from passed argument)"问题的原因及解决方法。

0