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

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

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

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

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

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

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

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

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

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

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, если есть две или более записей?

1 ответ

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

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

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

Удалось ли решить проблему? Для меня это выглядит как проблема с вашим http.client библиотека не совместима для запуска внутри облачных функций из-за ее асинхронного поведения вызова.

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

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

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

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

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

Другие вопросы по тегам