3

我有一個程序可以將來自不同市場營銷系統的廣告統計信息進行集中。一切工作正常,直到我將它轉換爲.exe格式並運行它。python請求在轉換爲.exe時找不到帶有證書的文件夾

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 1549, in __call__ 
    return self.func(*args) 
    File "C:\Users\user\Desktop\alg\TSK_7. Marketing\report_gui.py", line 24, in <lambda> 
    ok = tk.Button(root, text="DO NOT PRESS", bg="red", command=lambda: self.run()) 
    File "C:\Users\user\Desktop\alg\TSK_7. Marketing\report_gui.py", line 43, in run 
    report.merge_all() 
    File "C:\Users\user\Desktop\alg\TSK_7. Marketing\process_data.py", line 400, in merge_all 
    fb_df  = self.fetch_fb() 
    File "C:\Users\user\Desktop\alg\TSK_7. Marketing\process_data.py", line 156, in fetch_fb 
    fb_campaigns = from_fb.run_fb(self.start_date, self.end_date) # in JSON format 
    File "C:\Users\user\Desktop\alg\TSK_7. Marketing\from_fb.py", line 110, in run_fb 
    return s.get_stats() 
    File "C:\Users\user\Desktop\alg\TSK_7. Marketing\from_fb.py", line 84, in get_stats 
    params=params, 
    File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\adobjects\adaccount.py", line 1551, in get_insights 
    return request.execute() 
    File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\api.py", line 653, in execute 
    cursor.load_next_page() 
    File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\api.py", line 797, in load_next_page 
    params=self.params, 
    File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\api.py", line 305, in call 
    timeout=self._session.timeout 
    File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\sessions.py", line 508, in request 
    resp = self.send(prep, **send_kwargs) 
    File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\sessions.py", line 618, in send 
    r = adapter.send(request, **kwargs) 
    File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\adapters.py", line 407, in send 
    self.cert_verify(conn, request.url, verify, cert) 
    File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\adapters.py", line 226, in cert_verify 
    "invalid path: {0}".format(cert_loc)) 
OSError: Could not find a suitable TLS CA certificate bundle, invalid path: C:\Users\user\AppData\Local\Temp\_MEI253762\facebookads\fb_ca_chain_bundle.crt 

我試圖通過使用此代碼來解決這個問題,但MEI文件夾不斷變化的數字,每次我運行此代碼,以便它是沒有用的。

dst = r'C:\Users\user\AppData\Local\Temp\_MEI120642\facebookads' 
file = 'fb_ca_chain_bundle.crt' 

try: 
    os.makedirs(dst); ## it creates the destination folder 
except: 
    pass 

shutil.move(file, dst) 

讓我去這個文件

C:\用戶\用戶\應用程序數據\本地\程序\ Python的\ Python35 \ LIB \站點包\請求\ adapters.py

和試圖評論是否引發這種錯誤,但得到了SSL錯誤的語句。我找不到負責生成這些MEI數字的代碼。

def cert_verify(self, conn, url, verify, cert): 
    """Verify a SSL certificate. This method should not be called from user 
    code, and is only exposed for use when subclassing the 
    :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. 

    :param conn: The urllib3 connection object associated with the cert. 
    :param url: The requested URL. 
    :param verify: Either a boolean, in which case it controls whether we verify 
     the server's TLS certificate, or a string, in which case it must be a path 
     to a CA bundle to use 
    :param cert: The SSL certificate to verify. 
    """ 
    if url.lower().startswith('https') and verify: 

     cert_loc = None 

     # Allow self-specified cert location. 
     if verify is not True: 
      cert_loc = verify 

     if not cert_loc: 
      cert_loc = DEFAULT_CA_BUNDLE_PATH 

     if not cert_loc or not os.path.exists(cert_loc): 
      raise IOError("Could not find a suitable TLS CA certificate bundle, " 
          "invalid path: {0}".format(cert_loc)) 

     conn.cert_reqs = 'CERT_REQUIRED' 

     if not os.path.isdir(cert_loc): 
      conn.ca_certs = cert_loc 
     else: 
      conn.ca_cert_dir = cert_loc 
    else: 
     conn.cert_reqs = 'CERT_NONE' 
     conn.ca_certs = None 
     conn.ca_cert_dir = None 

    if cert: 
     if not isinstance(cert, basestring): 
      conn.cert_file = cert[0] 
      conn.key_file = cert[1] 
     else: 
      conn.cert_file = cert 
      conn.key_file = None 
     if conn.cert_file and not os.path.exists(conn.cert_file): 
      raise IOError("Could not find the TLS certificate file, " 
          "invalid path: {0}".format(conn.cert_file)) 
     if conn.key_file and not os.path.exists(conn.key_file): 
      raise IOError("Could not find the TLS key file, " 
          "invalid path: {0}".format(conn.key_file)) 
+0

我不得不把一個return語句就在cert_verify()函數的開始。這是非常骯髒和可怕的,但它的工作。 – Superbman

回答

2

我也遇到了這個問題。它看起來像來自程序編譯時沒有包含在requests軟件包目錄中的證書包cacert.pemrequests模塊使用函數certifi.core.where來確定cacert.pem的位置。覆蓋此函數並覆蓋由此函數設置的變量似乎可以解決問題。

我將此代碼添加到我的節目的開頭:

import sys, os 


def override_where(): 
    """ overrides certifi.core.where to return actual location of cacert.pem""" 
    # change this to match the location of cacert.pem 
    return os.path.abspath("cacert.pem") 


# is the program compiled? 
if hasattr(sys, "frozen"): 
    import certifi.core 

    os.environ["REQUESTS_CA_BUNDLE"] = override_where() 
    certifi.core.where = override_where 

    # delay importing until after where() has been replaced 
    import requests.utils 
    import requests.adapters 
    # replace these variables in case these modules were 
    # imported before we replaced certifi.core.where 
    requests.utils.DEFAULT_CA_BUNDLE_PATH = override_where() 
    requests.adapters.DEFAULT_CA_BUNDLE_PATH = override_where() 
相關問題