BeautifulSoup脚本单独运行与exec调用结果不一致问题求助
问题:exec调用Python脚本时BeautifulSoup无法定位目标元素
我遇到了这样的问题:单独运行script.py时,能正常解析网页并找到目标元素,但在main_script.py里用exec调用它时,目标元素始终找不到,判断结果一直是Non dispo。
目标HTML元素
<div class="stock available" title="Disponibilité"> <span> En stock </span> </div>
script.py代码
import requests from bs4 import BeautifulSoup headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.57' } page = requests.get("target_website.com", headers = headers, verify = False) html = BeautifulSoup(page.text, "html.parser") element_dispo = html.find('div', {'title':'Disponibilité'}) element_dispo = element_dispo.get('class') if element_dispo else [] dispo = 'Dispo' if 'available' in element_dispo else 'Non dispo'
main_script.py中的调用方式
with open("script.py") as file: exec(file.read())
已排查情况
- 单独运行
script.py完全正常,能正确识别元素 - 将两种运行方式下解析后的HTML保存为TXT对比,内容完全一致
- 环境:VS Code + Python 3.9
PS:用exec调用是因为这个脚本要爬大量URL生成CSV,我需要在打开输出CSV前执行它,同时也是为了整合同事的脚本到我的主脚本里。
解决方法
1. 改用模块导入替代exec
exec会在当前脚本的命名空间中执行代码,很容易和主脚本的变量、已导入库产生冲突(比如主脚本可能已有同名的requests/BeautifulSoup实例,或者同名变量干扰)。这是最可能的原因。
把script.py改成可导入模块:
- 修改
script.py,用函数封装逻辑:
import requests from bs4 import BeautifulSoup def check_disponibility(): headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.57' } page = requests.get("target_website.com", headers = headers, verify = False) html = BeautifulSoup(page.text, "html.parser") element_dispo = html.find('div', {'title':'Disponibilité'}) element_dispo = element_dispo.get('class') if element_dispo else [] dispo = 'Dispo' if 'available' in element_dispo else 'Non dispo' return dispo # 单独运行脚本时执行逻辑 if __name__ == "__main__": print(check_disponibility())
- 在
main_script.py中导入调用:
import script dispo_result = script.check_disponibility()
这种方式隔离了命名空间,符合Python代码规范,也能彻底避免冲突问题。
2. 若必须用exec,隔离命名空间
如果因为特殊原因要保留exec,可以给它指定独立的命名空间,避免和主脚本变量冲突:
with open("script.py") as file: # 用空字典作为全局、局部命名空间,隔离执行环境 exec(file.read(), {}, {})
3. 排查编码差异
虽然你说HTML内容一致,但可以检查两种运行方式下的编码是否有差异。在script.py中添加打印:
print(page.encoding) print(html.original_encoding)
如果编码不一致,尝试手动指定编码解析:
html = BeautifulSoup(page.content.decode('utf-8'), "html.parser")
内容的提问来源于stack exchange,提问作者BMML
相关产品推荐
相关产品推荐

