Jython 2.5.1:UnicodeDecodeError
最近我在尝试用Jython脚本从HTML文件中提取数据,使用的是QF-Test 3.5.4版本(注意,根据3.5.1版本的发布说明,支持的Python版本仅为2.5.1。 - http://www.qfs.de/en/qftest/relnotes.html#3.5.1)。
我使用的Python库(因为需要支持Python 2.x,所以这些库比较旧):
- html5lib 0.95
- BeautifulSoup 3.2.1
我在运行Xubuntu 13.10系统。
我的Jython脚本大概是这样的:
#Script uses obsolete Python libraries because QF-Test only supports Python 2.5.1
import urllib
#BeautifulSoup 3.2.1 - Python 2.x support
import BeautifulSoup
#html5lib 0.95 - has Python 2.5.1 support
from html5lib import sanitizer
from html5lib import treebuilders
#URL of HTML file that has been saved locally
url = 'Tlacovky/$(website)'
fp = urllib.urlopen(url)
#create HTML5 parser
parser = html5lib.HTMLParser(tree=treebuilders.getTreeBuilder("beautifulsoup"), tokenizer=sanitizer.HTMLSanitizer)
html5lib_object = parser.parse(file_pointer)
html_string = str(html5lib_object)
#load to BS
soup = BeautifulSoup(html_string)
for content in soup.findAll('script'):
print content
现在,当我尝试运行这个脚本,并且所有需要的变量都设置正确时,我遇到了这个问题:
UnicodeDecodeError: 'unicodeescape' codec can't decode bytes in position 48-54: illegal Unicode character
at org.python.core.PyException.fillInStackTrace(PyException.java:70)
at java.lang.Throwable.<init>(Throwable.java:181)
at java.lang.Exception.<init>(Exception.java:29)
at java.lang.RuntimeException.<init>(RuntimeException.java:32)
at org.python.core.PyException.<init>(PyException.java:46)
at org.python.core.PyException.doRaise(PyException.java:200)
at org.python.core.Py.makeException(Py.java:1171)
at org.python.core.Py.makeException(Py.java:1175)
at org.python.core.Py.makeException(Py.java:1179)
at org.python.core.Py.makeException(Py.java:1183)
at qfcommon$py.runscript$52(/opt/qftest/qftest-3.5.4/jython/Lib/qfcommon.py:962)
at qfcommon$py.call_function(/opt/qftest/qftest-3.5.4/jython/Lib/qfcommon.py)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyBaseCode.call(PyBaseCode.java:182)
at org.python.core.PyFunction.__call__(PyFunction.java:350)
at qftest$py.runscript$3(/opt/qftest/qftest-3.5.4/jython/Lib/qftest.py:91)
at qftest$py.call_function(/opt/qftest/qftest-3.5.4/jython/Lib/qftest.py)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyBaseCode.call(PyBaseCode.java:182)
at org.python.core.PyFunction.__call__(PyFunction.java:350)
at org.python.pycode._pyx386.f$0(<string>:1)
at org.python.pycode._pyx386.call_function(<string>)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1209)
at org.python.core.Py.exec(Py.java:1253)
at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:173)
at de.qfs.apps.qftest.shared.script.JythonEngine.exec(SourceFile:195)
at org.apache.bsf.BSFManager$6.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.bsf.BSFManager.exec(Unknown Source)
at de.qfs.apps.qftest.run.RMIRunContext.runScript(SourceFile:1875)
... 16 more
我成功找到了问题的根源,出在导入“inputstream.py”这个文件上,错误就是在这里发生的。
我真的是快抓狂了。如果你能帮我解决这个问题,我将非常感激。
编辑:
通过修改inputstream.py解决了这个问题:
invalid_unicode_re = re.compile("[\u0001-\u0008\u000B\u000E-\u001F\u007F-\u009F\uD800-\uDFFF\uFDD0-\uFDEF\uFFFE\uFFFF\U0001FFFE\U0001FFFF\U0002FFFE\U0002FFFF\U0003FFFE\U0003FFFF\U0004FFFE\U0004FFFF\U0005FFFE\U0005FFFF\U0006FFFE\U0006FFFF\U0007FFFE\U0007FFFF\U0008FFFE\U0008FFFF\U0009FFFE\U0009FFFF\U000AFFFE\U000AFFFF\U000BFFFE\U000BFFFF\U000CFFFE\U000CFFFF\U000DFFFE\U000DFFFF\U000EFFFE\U000EFFFF\U000FFFFE\U000FFFFF\U0010FFFE\U0010FFFF]")
#Craziness
if len("\U0010FFFF") == 1:
self.reportCharacterErrors = self.characterErrorsUCS4
self.replaceCharactersRegexp = re.compile("[\uD800-\uDFFF]")
else:
self.reportCharacterErrors = self.characterErrorsUCS2
self.replaceCharactersRegexp = re.compile("([\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF])")
1 个回答
1
[在2016年中期进行了大幅重写,以更新内容。]
html5lib不支持Jython 2.5,这一点从来没有改变。虽然在html5lib 0.9999版本中引入了一定程度的支持,但那需要使用Jython 2.7(值得注意的是,支持并不是百分之百保证的,但原则上是可以工作的)。
如果你想尝试让它在Jython 2.5上运行,你需要做的事情可不止是替换invalid_unicode_re
,具体情况可以查看这个问题。我建议你在修改后尝试运行测试套件。此外,现在我们要求至少使用Python 2.6,而支持任何2.5的变种将需要大量的工作。