Доступ к https страницам с помощью python3 - PullRequest
0 голосов
/ 24 октября 2018

Я не понимаю, как использовать urllib3 или requests для подключения к веб-сайту https.Это сводит меня с ума.Я установил certifi и вижу файл по умолчанию .pem, который он предоставляет.Я попытался установить для параметра requests.verify значение requests для каждого файла .pem и .crt на компьютере, на котором выполняется мой сценарий [Я не являюсь администратором на этом устройстве].Я получаю только ошибки.

Я перешел на использование urllib3 и теперь получаю:

H:\Projects\MyScraper\venv\Scripts\python.exe H:/Projects/MyScraper/MyScraper.py
Traceback (most recent call last):
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 343, in _make_request
    self._validate_conn(conn)
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 839, in _validate_conn
    conn.connect()
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connection.py", line 344, in connect
    ssl_context=context)
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\util\ssl_.py", line 342, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "C:\Program Files (x86)\Python36-32\lib\ssl.py", line 407, in wrap_socket
    _context=self, _session=session)
  File "C:\Program Files (x86)\Python36-32\lib\ssl.py", line 814, in __init__
    self.do_handshake()
  File "C:\Program Files (x86)\Python36-32\lib\ssl.py", line 1068, in do_handshake
    self._sslobj.do_handshake()
  File "C:\Program Files (x86)\Python36-32\lib\ssl.py", line 689, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "H:/Projects/MyScraper/MyScraper.py", line 15, in <module>
    raw_html = HTTP.request('GET', 'https://portal.xsede.org/course-calendar/')
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\request.py", line 68, in request
    **urlopen_kw)
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\request.py", line 89, in request_encode_url
    return self.urlopen(method, url, **extra_kw)
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\poolmanager.py", line 323, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 667, in urlopen
    **response_kw)
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 667, in urlopen
    **response_kw)
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 667, in urlopen
    **response_kw)
  [Previous line repeated 6 more times]
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 638, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\util\retry.py", line 398, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='portal.xsede.org', port=443): Max retries exceeded with url: /course-calendar/ (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)'),))

Process finished with exit code 1

Мой код выглядит так:

    #!/home/me/virtualenv/python3.6/3.6/bin/python

    import certifi
    import urllib3
    from bs4 import BeautifulSoup

    HTTP = urllib3.PoolManager(
        cert_reqs='CERT_REQUIRED',
        ca_certs=certifi.where(),
        retries=10
    )

    raw_html = HTTP.request('GET', 'https://portal.xsede.org/course-calendar/')

    html = BeautifulSoup(raw_html, 'html.parser')

Он взрываетсяна линии raw_html = HTTP.request(....Идеи?

Редактировать

Да, это как-то связано с моим целевым хостом.Если я перейду к google.com, то несколько моих файлов pem / crt сработают.

1 Ответ

0 голосов
/ 24 октября 2018

Проблема в том, что вы используете неверный сертификат для отправки запроса.

вы можете запустить эту команду, чтобы проверить, какой сертификат используется при выполнении любого запроса, а затем использовать этот сертификат в своем запросе,

openssl s_client -showcerts -connect google.com:443

Также убедитесь, что вы передаете verify путь к CA_BUNDLE файлу или каталогу с сертификатами доверенных ЦС.

Этот список доверенных ЦС также можно указать черезREQUESTS_CA_BUNDLE переменная окружения.

Если это не сработает, вы можете явно объединить настройки среды в сеанс ,

Когда вы используетеПодготовив поток запросов, имейте ввиду, что он не учитывает среду.Это может вызвать проблемы, если вы используете переменные среды для изменения поведения запросов.Например: самоподписанные сертификаты SSL, указанные в REQUESTS_CA_BUNDLE, не будут приняты во внимание.В результате выдается SSL: CERTIFICATE_VERIFY_FAILED.Вы можете обойти это поведение, объединив настройки среды с вашим сеансом:

из запросов на импорт запросов, сеанс

s = Session()
req = Request('GET', url)

prepped = s.prepare_request(req)

# Merge environment settings into session
settings = s.merge_environment_settings(prepped.url, None, None, None, None)
resp = s.send(prepped, **settings)

print(resp.status_code)
...