python--将模块名称导入为变量(动态加载传递的参数中的模块)
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, inmodule_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 ...
问题出现的原因是因为需要根据传递的参数动态加载模块,但是在使用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)"问题的原因及解决方法。