Как сделать запрос PUT в Python для цикла

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

Машин очень много, более 100 тысяч. Таким образом, выполнение этого один раз (в одном процессе) заняло бы слишком много времени, и это невозможно сделать таким образом.

Таким образом, мне нужно делать это в более мелких процессах, а не в одном большом процессе.

Если я правильно понимаю, это можно сделать с помощью функций IBM Cloud.

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

Таким образом, у меня было бы (вместо одного большого процесса) много более мелких процессов, и это заняло бы меньше времени.

Идея заключается в следующем:

  • Вызовите действие, которое получит все makes и прокрутит их. И для каждого make сначала создайте и выполните действие, а затем вызовите его.

Код выглядит следующим образом:

import sys
import os
import json
import requests
import http.client
import uuid

API_URL = "https://url.com"
APIHOST = os.environ.get('__OW_API_HOST')
NAMESPACE = os.environ.get('__OW_NAMESPACE')
USER_PASS = os.environ.get('__OW_API_KEY').split(':')

code = "New function code"

makes = [
    {"id": 9,"name": "Audi"},
    {"id": 74,"name": "Volkswagen"}
]

def main(dict):
    conn = http.client.HTTPSConnection("openwhisk.eu-gb.bluemix.net")
    payload = json.dumps({"exec": {"kind": "python-jessie:3", "code": code}})
    headers = {
        'accept': "application/json",
        'content-type': "application/json",
        'Authorization': "Basic my-base64key"
    }

    for make in makes:
        action = 'models-{0}'.format(make['name'])
        url = APIHOST + '/api/v1/namespaces/' + NAMESPACE + '/actions/' + action + "?overwrite=true"

        conn.request("PUT", url, payload, headers) // Create new action
        // Execute the new action

    return {"Success": "Main executed correctly."}

Проблема в цикле for. Если есть только одна марка, то это работает нормально. Но если их два или больше, это не работает. Я получаю сообщение об ошибке следующим образом:

[
    "2018-07-11T08:53:06.322665342Z stderr: Traceback (most recent call last):",
    "2018-07-11T08:53:06.322685254Z stderr: File \"pythonrunner.py\", line 88, in run",
    "2018-07-11T08:53:06.322692936Z stderr: exec('fun = %s(param)' % self.mainFn, self.global_context)",
    "2018-07-11T08:53:06.322699124Z stderr: File \"<string>\", line 1, in <module>",
    "2018-07-11T08:53:06.322705761Z stderr: File \"__main__.py\", line 71, in main",
    "2018-07-11T08:53:06.322712082Z stderr: File \"/usr/local/lib/python3.6/http/client.py\", line 1239, in request",
    "2018-07-11T08:53:06.322718524Z stderr: self._send_request(method, url, body, headers, encode_chunked)",
    "2018-07-11T08:53:06.322724518Z stderr: File \"/usr/local/lib/python3.6/http/client.py\", line 1250, in _send_request",
    "2018-07-11T08:53:06.322730924Z stderr: self.putrequest(method, url, **skips)",
    "2018-07-11T08:53:06.322736931Z stderr: File \"/usr/local/lib/python3.6/http/client.py\", line 1108, in putrequest",
    "2018-07-11T08:53:06.322742876Z stderr: raise CannotSendRequest(self.__state)",
    "2018-07-11T08:53:06.322748626Z stderr: http.client.CannotSendRequest: Request-sent"
]

Любая идея, как я могу выполнять эти запросы внутри цикла for, если есть две или более записей?


person Boky    schedule 11.07.2018    source источник
comment
Вы должны получить ответ перед отправкой новых запросов. Я думаю, что эта ссылка может быть полезной link1   -  person Domenico Vito Scalera    schedule 11.07.2018


Ответы (2)


Разделение процесса искателя на отдельные вызовы действий — разумный подход к выполнению этой работы в IBM Cloud Functions.

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

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

person James Thomas    schedule 17.07.2018

Удалось решить проблему? Мне кажется, что проблема с вашей библиотекой http.client несовместима с запуском внутри Cloud Functions из-за ее асинхронного поведения при вызове.

Согласно документации Python, вы не должны использовать эту библиотеку напрямую. Вместо этого используйте настоятельно рекомендуемый модуль requests.

http.client — клиент протокола HTTP Исходный код: Lib/http/client.py

Этот модуль определяет классы, реализующие клиентскую часть протоколов HTTP и HTTPS. Обычно он не используется напрямую — модуль urllib.request использует его для обработки URL-адресов, использующих HTTP и HTTPS.

См. также Пакет Requests рекомендуется для клиентского HTTP-интерфейса более высокого уровня.

https://docs.python.org/3/library/http.client.html

person Imran    schedule 25.12.2018