Проблема и результат
При использовании моего скрипта python я получаю тот же ответ от вызова API, возвращающего json, и, похоже, это происходит в течение нескольких часов одновременно.
Я использую Coindesk BPI API, который обновляется раз в минуту. . Итак, как мы знаем, цена Биткойна не остается на одном уровне в течение 5 часов. См. Пример вывода ниже:
# results.txt
{"timestamp": 16-Apr-2020 22:50, "price": 7078, "gCount": 28, "rCount": 48}
{"timestamp": 16-Apr-2020 23:00, "price": 7085, "gCount": 29, "rCount": 50}
{"timestamp": 16-Apr-2020 23:10, "price": 7011, "gCount": 33, "rCount": 52}
{"timestamp": 16-Apr-2020 23:20, "price": 7002, "gCount": 31, "rCount": 55}
{"timestamp": 16-Apr-2020 23:30, "price": 7020, "gCount": 30, "rCount": 52}
{"timestamp": 16-Apr-2020 23:40, "price": 7027, "gCount": 33, "rCount": 54}
{"timestamp": 16-Apr-2020 23:50, "price": 7047, "gCount": 35, "rCount": 58}
{"timestamp": 17-Apr-2020 00:01, "price": 7060, "gCount": 36, "rCount": 57}
{"timestamp": 17-Apr-2020 00:10, "price": 7051, "gCount": 34, "rCount": 45}
{"timestamp": 17-Apr-2020 00:20, "price": 7052, "gCount": 41, "rCount": 48}
{"timestamp": 17-Apr-2020 00:31, "price": 7054, "gCount": 47, "rCount": 48}
# It worked! Now the price is stuck for 2 get requests.
{"timestamp": 17-Apr-2020 00:40, "price": 7054, "gCount": 48, "rCount": 47}
{"timestamp": 17-Apr-2020 00:50, "price": 7054, "gCount": 50, "rCount": 48}
{"timestamp": 17-Apr-2020 01:01, "price": 7051, "gCount": 48, "rCount": 43}
# Price stuck again for around 30 get requests.
{"timestamp": 17-Apr-2020 01:10, "price": 7051, "gCount": 46, "rCount": 47}
{"timestamp": 17-Apr-2020 01:20, "price": 7051, "gCount": 49, "rCount": 46}
{"timestamp": 17-Apr-2020 01:30, "price": 7051, "gCount": 48, "rCount": 47}
{"timestamp": 17-Apr-2020 01:40, "price": 7051, "gCount": 50, "rCount": 48}
{"timestamp": 17-Apr-2020 01:50, "price": 7051, "gCount": 50, "rCount": 52}
{"timestamp": 17-Apr-2020 02:00, "price": 7051, "gCount": 51, "rCount": 56}
{"timestamp": 17-Apr-2020 02:10, "price": 7051, "gCount": 50, "rCount": 55}
{"timestamp": 17-Apr-2020 02:20, "price": 7051, "gCount": 57, "rCount": 57}
{"timestamp": 17-Apr-2020 02:30, "price": 7051, "gCount": 48, "rCount": 54}
{"timestamp": 17-Apr-2020 02:40, "price": 7051, "gCount": 52, "rCount": 54}
{"timestamp": 17-Apr-2020 02:51, "price": 7051, "gCount": 54, "rCount": 57}
{"timestamp": 17-Apr-2020 03:00, "price": 7051, "gCount": 53, "rCount": 59}
{"timestamp": 17-Apr-2020 03:11, "price": 7051, "gCount": 53, "rCount": 59}
{"timestamp": 17-Apr-2020 03:21, "price": 7051, "gCount": 50, "rCount": 55}
{"timestamp": 17-Apr-2020 03:31, "price": 7051, "gCount": 51, "rCount": 55}
{"timestamp": 17-Apr-2020 03:41, "price": 7051, "gCount": 52, "rCount": 56}
{"timestamp": 17-Apr-2020 03:51, "price": 7051, "gCount": 50, "rCount": 55}
{"timestamp": 17-Apr-2020 04:01, "price": 7051, "gCount": 48, "rCount": 56}
{"timestamp": 17-Apr-2020 04:10, "price": 7051, "gCount": 39, "rCount": 50}
{"timestamp": 17-Apr-2020 04:20, "price": 7051, "gCount": 39, "rCount": 49}
{"timestamp": 17-Apr-2020 04:31, "price": 7051, "gCount": 41, "rCount": 53}
{"timestamp": 17-Apr-2020 04:40, "price": 7051, "gCount": 43, "rCount": 53}
{"timestamp": 17-Apr-2020 04:50, "price": 7051, "gCount": 39, "rCount": 51}
{"timestamp": 17-Apr-2020 05:00, "price": 7051, "gCount": 37, "rCount": 52}
{"timestamp": 17-Apr-2020 05:11, "price": 7051, "gCount": 38, "rCount": 54}
{"timestamp": 17-Apr-2020 05:20, "price": 7051, "gCount": 31, "rCount": 49}
{"timestamp": 17-Apr-2020 05:30, "price": 7051, "gCount": 0, "rCount": 0}
{"timestamp": 17-Apr-2020 05:41, "price": 7051, "gCount": 32, "rCount": 49}
{"timestamp": 17-Apr-2020 05:50, "price": 7051, "gCount": 37, "rCount": 49}
{"timestamp": 17-Apr-2020 06:01, "price": 7051, "gCount": 39, "rCount": 51}
{"timestamp": 17-Apr-2020 06:11, "price": 7051, "gCount": 41, "rCount": 47}
{"timestamp": 17-Apr-2020 06:21, "price": 7051, "gCount": 42, "rCount": 46}
# Now it works again as intended.
{"timestamp": 17-Apr-2020 06:31, "price": 7082, "gCount": 45, "rCount": 49}
{"timestamp": 17-Apr-2020 06:40, "price": 7084, "gCount": 48, "rCount": 50}
{"timestamp": 17-Apr-2020 06:51, "price": 7095, "gCount": 45, "rCount": 51}
{"timestamp": 17-Apr-2020 07:01, "price": 7097, "gCount": 44, "rCount": 45}
{"timestamp": 17-Apr-2020 07:11, "price": 7068, "gCount": 45, "rCount": 46}
{"timestamp": 17-Apr-2020 07:21, "price": 7070, "gCount": 43, "rCount": 45}
Сценарий Python и то, что я пробовал
Я использую python 2.7 и запросы. По умолчанию запросы не кешируются. Итак, я подумал, что соединение просто остается случайным, и python повторно использует его, получая тот же json.
Я попытался закрыть сеанс запросов, установив для значения false с помощью используя блок with и попробовав requests.session (). close () < / а>. Ниже вы найдете соответствующий код Python:
import requests, json, sys, time
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
def request_json():
print 'Begin request to get the json...'
# Try get request once
response = requests_retry_session().get('https://api.coindesk.com/v1/bpi/currentprice/USD.json')
if (response.status_code == 200):
# Close the connection
# requests.session().close() <-- tried, doesn't do the trick
print 'Fetched price succesfully.\n'
return response.json()
# If first request didn't succeed, retry 3 times using session
with requests.Session() as s:
s.get('https://api.coindesk.com/v1/bpi/currentprice/USD.json')
# Close the connection
# s.config['keep_alive'] = False <-- tried, doesn't do the trick
response = requests_retry_session(session=s).get(
'https://api.coindesk.com/v1/bpi/currentprice/USD.json'
)
# When requests succeed using session
if (response.status_code == 200):
# Close the connection
# requests.session().close() <-- tried, doesn't do the trick
print 'Fetched price succesfully.\n'
return response.json()
print 'Couldn\'t fetch price json.'
return 'error'
def requests_retry_session(
retries=3,
backoff_factor=0.3,
status_forcelist=(500, 502, 504),
session=None,
):
session = session or requests.Session()
retry = Retry(
total=retries,
read=retries,
connect=retries,
backoff_factor=backoff_factor,
status_forcelist=status_forcelist,
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('https://', adapter)
return session
def get_price_data(json):
price = str(json['bpi']['USD']['rate'])
# Strip the ',' from price, convert to float and to int
price = int(float(price.replace(',', '')))
return price
def main():
# Send a request for the bitcoin price json
priceJson = request_json()
# Check if the request and retries failed
if (json == 'error'):
print 'Terminating bitcoinPrice.py script.'
sys.exit()
# Get the data from the response json
priceInt = get_price_data(priceJson)
# Get timestamp as milliseconds
milli_sec = int(round(time.time() * 1000))
# Read the colordata from colors.txt
# The format is: '63,61' where greenCount,redCount
fh = open('colors.txt', 'r')
colorData = fh.read()
gCount = colorData.split(',')[0]
rCount = colorData.split(',')[1]
# Create a string in json format with the price and color data
dataString = "{\"timestamp\": \"%d\", \"price\": \"%d\", \"gCount\": \"%s\", \"rCount\": \"%s\"}" % (milli_sec, priceInt, gCount, rCount)
print dataString
# Read and write to results.txt
fh = open('results/results.txt', 'a')
fh.write(dataString + '\n')
fh.close()
print '\nSuccesfully saved BTC price and color data to results.txt'
if __name__ == '__main__':
main()
Мне не удалось воспроизвести ошибку, каждую минуту выполняя crontab от имени обычного пользователя и используя только этот скрипт bitcoinPrice.py.
Кажется, что ошибка возникает, когда мой корневой crontab запускается каждые 10 минут, когда перед этим запускается еще пара скриптов. Фактический crontab, запускаемый пользователем root, упрощен и имеет другие сценарии, связанные следующим образом:
*/10 * * * * node script1.js && python2 script2.py && python2 bitcoinPrice.py && /home/user/clearcache.sh
Все остальные скрипты работают по назначению. Последний сценарий, clearcache.sh, сбрасывает кеши и буферы, как описано здесь ниже. способ:
#!/bin/sh
sync; echo 3 > /proc/sys/vm/drop_caches
Я хотел бы узнать, что с этой ошибкой. В случае, если я не могу найти решение, я перейду к использованию curl и выгрузу ответ API json в файл и прочитал его оттуда. Любые идеи приветствуются!
1 ответ
Мне удалось это решить. При регулярном использовании curl проблема сохранялась, но я использовал эти ответы ( https://stackoverflow.com/a/42263514/12965126) и добавил уникальный параметр запроса (время эпохи в мс) для каждого запроса? $ (дата +% s).
curl https://api.coindesk.com/v1/bpi/currentprice/USD.json?$(date +%s) -o results/priceJson.txt
... и работает без кешей. Теперь будет работать с запросами python, используя тот же трюк.
Похожие вопросы
Связанные вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.