@spiller1975
давайте не будем поучать и умничать!

Как устранить ошибку «TooManyRedirects: Exceeded 30 redirects» при выполнении скрипта Python?

Здравствуйте.

Начинаю изучать Python, прошу помощи!
В интернете нашел нужный мне скрипт для управления модемом Huawei E5186 через встроенный API.
Использую Python 2.7 под Windows 7, все нужные модули установлены.
В процессе тестов нашел рабочий вариант в моей ситуации

вот текст скрипта
#!/usr/bin/env python

from __future__ import unicode_literals
#from PyCRC.CRC16 import CRC16

import requests
import re
import hashlib
import base64
import os, sys

def reboot(baseurl, session):
    data='<request><Control>1</Control></request>'
    r= session.post(baseurl + "api/device/control", data=data)
    
def login(baseurl, username, password):
    s = requests.Session()
    r = s.get(baseurl + "html/home.html")
    csrf_tokens = grep_csrf(r.text)
    headers_update(s.headers, csrf_tokens[1])
    data = login_data(username, password, str(csrf_tokens[1]))
    r = s.request('POST', baseurl + "api/user/login", data=data)
    s.headers.update({'__RequestVerificationToken': r.headers["__requestverificationtokenone"]})
    return s

def headers_update(dictbase, token):
    dictbase['Accept-Language'] = 'en-US'
    dictbase['Content-Type'] = 'application/x-www-form-urlencoded'
    dictbase['X-Requested-With'] = 'XMLHttpRequest'
    dictbase['__RequestVerificationToken'] = token
    dictbase['Cache-Control'] = 'no-cache'
    dictbase['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/600.8.9 (KHTML, like Gecko) Version/8.0.8 Safari/600.8.9'
    
def grep_csrf(html):
    pat = re.compile(r".*meta name=\"csrf_token\" content=\"(.*)\"", re.I)
    matches = (pat.match(line) for line in html.splitlines())
    return [m.group(1) for m in matches if m]

def login_data(username, password, csrf_token):
    def encrypt(text):
        m = hashlib.sha256()
        m.update(text)
        return base64.b64encode(m.hexdigest())
    password_hash = encrypt(username + encrypt(password) + csrf_token)
    return '<?xml version "1.0" encoding="UTF-8"?><request><Username>%s</Username><Password>%s</Password><password_type>4</password_type></request>' % (username, password_hash)

baseurl = "http://192.168.1.1/"
username = "admin"
password = "admin"

if __name__ == "__main__":
    print "Trying to log in..."
    s = login(baseurl, username, password)
    print "Logged ! Trying to reboot..."
    reboot(baseurl, s)
</code</spoiler>>
Этот скрипт перезагружает устройство, он работает.

Мне нужны несколько другие возможности API, поэтому пытаюсь задействовать другие функции.
Для смены режима работы сети 4G роутера пытаюсь запускать 

<spoiler title="такой скрипт"><code lang="python">
import requests
import re
import hashlib
import base64
import os, sys

def changemode(baseurl, session):
    data='<request><NetworkMode>03</NetworkMode></request>'
    r= session.post(baseurl + "/api/net/net-mode", data=data)
    
    
def login(baseurl, username, password):
    s = requests.Session()
    r = s.get(baseurl + "html/home.html")
    csrf_tokens = grep_csrf(r.text)
    headers_update(s.headers, csrf_tokens[1])
    data = login_data(username, password, str(csrf_tokens[1]))
    r = s.request('POST', baseurl + "api/user/login", data=data)
    s.headers.update({'__RequestVerificationToken': r.headers["__requestverificationtokenone"]})
    return s

def headers_update(dictbase, token):
    dictbase['Accept-Language'] = 'en-US'
    dictbase['Content-Type'] = 'application/x-www-form-urlencoded'
    dictbase['X-Requested-With'] = 'XMLHttpRequest'
    dictbase['__RequestVerificationToken'] = token
    dictbase['Cache-Control'] = 'no-cache'
    dictbase['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/600.8.9 (KHTML, like Gecko) Version/8.0.8 Safari/600.8.9'
    
def grep_csrf(html):
    pat = re.compile(r".*meta name=\"csrf_token\" content=\"(.*)\"", re.I)
    matches = (pat.match(line) for line in html.splitlines())
    return [m.group(1) for m in matches if m]

def login_data(username, password, csrf_token):
    def encrypt(text):
        m = hashlib.sha256()
        m.update(text)
        return base64.b64encode(m.hexdigest())
    password_hash = encrypt(username + encrypt(password) + csrf_token)
    return '<?xml version "1.0" encoding="UTF-8"?><request><Username>%s</Username><Password>%s</Password><password_type>4</password_type></request>' % (username, password_hash)

baseurl = "http://192.168.1.1/"
username = "admin"
password = "admin"

if __name__ == "__main__":
    s = login(baseurl, username, password)
    changemode(baseurl, s)
</code></spoiler>

Получая ошибку:

<code>Traceback (most recent call last):
  File "D:\scripts\morereboot.py", line 54, in <module>
    changemode(baseurl, s)
  File "D:\scripts\morereboot.py", line 14, in changemode
    r= session.post(baseurl + "/api/net/net-mode", data=data)
  File "C:\Python27\lib\site-packages\requests-2.22.0-py2.7.egg\requests\sessions.py", line 581, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "C:\Python27\lib\site-packages\requests-2.22.0-py2.7.egg\requests\sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Python27\lib\site-packages\requests-2.22.0-py2.7.egg\requests\sessions.py", line 668, in send
    history = [resp for resp in gen] if allow_redirects else []
  File "C:\Python27\lib\site-packages\requests-2.22.0-py2.7.egg\requests\sessions.py", line 165, in resolve_redirects
    raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp)
TooManyRedirects: Exceeded 30 redirects.</code>

Поискал в сети, пишут какая-то проблема с заголовком User-Agent или с кукисами.

Подскажите как избавится от ошибки!
  • Вопрос задан
  • 105 просмотров
Пригласить эксперта
Ответы на вопрос 1
@crazywu
А разве там не инфити луп на changemode? Если я правильно понял, то эта функция вызывает редиррект. И получается, что это будет происходить до тех пор пока __name__ == "__main__". И, мне показалось, что __name__ не изменит значение во время выполнения changemode (могу ошибаться)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
OnederX Москва
от 100 000 до 120 000 ₽
iCode Москва
от 90 000 до 200 000 ₽
SwapZilla.co Сочи
от 200 000 ₽
05 июл. 2020, в 13:35
50000 руб./за проект
05 июл. 2020, в 13:11
3000 руб./за проект
05 июл. 2020, в 12:50
1000 руб./за проект