macOS 10.12
I'm trying to package a python script (called getUrls_douyu.py
) as a standalone application/executable without dependencies, so I'm using py2app. The problem is that when I try to run my app after building (from terminal with: open getUrls_douyu.app
), nothing happens and I get the following error prompt:
The console error:
Detected missing constraints for <private>. It cannot be placed because there are not enough constraints to fully define the size and origin. Add the missing constraints, or set translatesAutoresizingMaskIntoConstraints=YES and constraints will be generated for you. If this view is laid out manually on macOS 10.12 and later, you may choose to not call [super layout] from your override. Set a breakpoint on DETECTED_MISSING_CONSTRAINTS to debug. This error will only be logged once.
If I try open getUrls_douyu.app/Contents/MacOS/getUrls_douyu
(the executable inside the app bundle), I get a different error:
IOError: Could not find a suitable TLS CA certificate bundle, invalid path: /Users/<REDACTED>/getUrls_douyu/dist/getUrls_douyu.app/Contents/Resources/lib/python2.7/site-packages.zip/certifi/cacert.pem
But I checked and cacert.pem does indeed exist there, so for some reason the certificate is invalid? My .py script uses requests
module to get stuff from a webpage which I think must be the issue. Here's my full python script:
import requests
from bs4 import BeautifulSoup
html = requests.get('https://www.douyu.com/directory/all').text
soup = BeautifulSoup(html, 'html.parser')
urls = soup.select('.play-list-link')
output = '';
output += '[' #open json array
for i, url in enumerate(urls):
channelName = str(i);
channelUrl = 'http://douyu.com' + url.get('href')
output += '{'
output += '\"channelName\":' + '\"' + channelName.encode('utf-8') + '\",'
output += '\"channelUrl\":' + '\"' + channelUrl.encode('utf-8') + '\"'
output += '},'
output = output[:-1]
output += ']'
print output
When I first built this script I did so in a virtualenv within which I've done pip install requests
and pip install beautifulsoup4
and tested that the script successfully ran with no problem.
This answer to a question regarding the cacert.pem error with the requests module did not help me. Here is my python script when applying that given solution:
import requests
from bs4 import BeautifulSoup
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()
html = requests.get('https://www.douyu.com/directory/all').text
soup = BeautifulSoup(html, 'html.parser')
urls = soup.select('.play-list-link')
output = '';
output += '[' #open json array
for i, url in enumerate(urls):
channelName = str(i);
channelUrl = 'http://douyu.com' + url.get('href')
output += '{'
output += '\"channelName\":' + '\"' + channelName.encode('utf-8') + '\",'
output += '\"channelUrl\":' + '\"' + channelUrl.encode('utf-8') + '\"'
output += '},'
output = output[:-1]
output += ']'
print output
I think I've set up my py2app setup.py file correctly...
from setuptools import setup
APP = ['getUrls_douyu.py']
DATA_FILES = []
OPTIONS = {}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
Sorry for the verbose question! I'm new-ish to python so I imagine I've made some dumb mistake. Any help GREATLY appreciated.