使用Python Shareplum访问本地SharePoint文件遇JSON解析错误求助
问题现象
我有一个SharePoint 2013站点,用Python脚本访问文档列表时,凭证验证正常,调用site.GetListCollection()也能返回包含目标文档库的数据:
from shareplum import Site from shareplum.site import Version from getpass import getpass as pwd from requests_ntlm import HttpNtlmAuth server_url = "https://sharepoint.company.net" site_url = server_url + "/sites/<sitename>" user_id = <user id> pwd = pwd("Enter Password") cred = HttpNtlmAuth(sid, pwd) site = Site(site_url, auth=cred, version=Version.v2013)
但执行folder = site.Folder('Shared Documents')时触发JSONDecodeError,服务器返回XML格式的ContextWebInformation而非预期的JSON,错误详情如下:
--------------------------------------------------------------------------- JSONDecodeError Traceback (most recent call last) File c:\jpy\lib\site-packages\requests\models.py:910, in Response.json(self, **kwargs) 909 try: --> 910 return complexjson.loads(self.text, **kwargs) 911 except JSONDecodeError as e: 912 # Catch JSON-related errors and raise as requests.JSONDecodeError 913 # This aliases json.JSONDecodeError and simplejson.JSONDecodeError File C:\ds\tools\python3.8\latest\lib\json\__init__.py:357, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw) 354 if (cls is None and object_hook is None and 355 parse_int is None and parse_float is None and 356 parse_constant is None and object_pairs_hook is None and not kw): --> 357 return _default_decoder.decode(s) 358 if cls is None: File C:\ds\tools\python3.8\latest\lib\json\decoder.py:337, in JSONDecoder.decode(self, s, _w) 333 """Return the Python representation of ``s`` (a ``str`` instance 334 containing a JSON document). 335 336 """ --> 337 obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 338 end = _w(s, end).end() File C:\ds\tools\python3.8\latest\lib\json\decoder.py:355, in JSONDecoder.raw_decode(self, s, idx) 354 except StopIteration as err: --> 355 raise JSONDecodeError("Expecting value", s, err.value) from None 356 return obj, end JSONDecodeError: Expecting value: line 1 column 1 (char 0) During handling of the above exception, another exception occurred: JSONDecodeError Traceback (most recent call last) Input In [24], in <cell line: 1>() ----> 1 folder = site.Folder('Shared Documents') File c:\jpy\lib\site-packages\shareplum\folder.py:12, in _Folder.__init__(self, session, folder_name, url) 9 self.site_url = url 10 self.timeout = 3 ---> 12 self.info = self._create_folder() File c:\jpy\lib\site-packages\shareplum\folder.py:30, in _Folder._create_folder(self) 24 body = json.dumps(update_data) 26 url = self.site_url + f"/_api/web/folders" 28 headers = {'Accept': 'application/json;odata=verbose', 29 'Content-Type': 'application/json;odata=verbose', ---> 30 'X-RequestDigest': self.contextinfo['FormDigestValue']} 32 response = post(self._session, url=url, headers=headers, data=body, timeout=self.timeout) 34 return response.json() File c:\jpy\lib\site-packages\shareplum\folder.py:17, in _Folder.contextinfo(self) 14 @property 15 def contextinfo(self): 16 response = post(self._session, self.site_url + "/_api/contextinfo") ---> 17 data = response.json() 18 return data File c:\jpy\lib\site-packages\requests\models.py:917, in Response.json(self, **kwargs) 915 raise RequestsJSONDecodeError(e.message) 916 else: ---> 917 raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) JSONDecodeError: [Errno Expecting value] <?xml version="1.0" encoding="utf-8"?> <d:GetContextWebInformation xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:type="SP.ContextWebInformation"> <d:FormDigestTimeoutSeconds m:type="Edm.Int32">1800</d:FormDigestTimeoutSeconds> <d:FormDigestValue>0xuniqueid,20 Jul 2022 19:26:02 -0000</d:FormDigestValue> <d:LibraryVersion>15.0.5067.1000</d:LibraryVersion> <d:SiteFullUrl>https://sharepoint.company.net/sites/sitename</d:SiteFullUrl> <d:SupportedSchemaVersions m:type="Collection(Edm.String)"> <d:element>14.0.0.0</d:element> <d:element>15.0.0.0</d:element> </d:SupportedSchemaVersions> <d:WebFullUrl>https://sharepoint.company.net/sites/sitename</d:WebFullUrl> </d:GetContextWebInformation>: 0
问题原因与解决方案
错误核心是SharePoint 2013的/_api/contextinfo端点默认返回XML格式,但shareplum库的_Folder.contextinfo属性直接调用response.json()解析,导致格式不匹配。以下是三种可行解决方法:
方法1:修改请求头强制返回JSON
打开c:\jpy\lib\site-packages\shareplum\folder.py,找到contextinfo属性,修改为:
@property def contextinfo(self): headers = {'Accept': 'application/json;odata=verbose'} response = post(self._session, self.site_url + "/_api/contextinfo", headers=headers) data = response.json() return data['d']
添加Accept头后,服务器会返回JSON格式的ContextWebInformation,可正常解析。
方法2:直接通过列表API访问文档库
既然site.GetListCollection()能正常返回数据,可绕过Folder方法,直接操作列表对象:
# 获取文档库列表对象 doc_lib = site.List('Shared Documents') # 获取根文件夹下的文件 items = doc_lib.GetListItems() # 精准获取文件夹详情 folder_items = doc_lib.GetListItems(query={'Where': ['Eq', 'FileDirRef', '/sites/<sitename>/Shared Documents']})
方法3:降级shareplum版本
部分新版本shareplum对SharePoint 2013兼容性不足,可降级到0.5.1版本:
pip install shareplum==0.5.1
旧版本的Folder方法针对SharePoint 2013做了适配,不会出现XML解析错误。
内容的提问来源于stack exchange,提问作者Mat Mellon
相关产品推荐
相关产品推荐

