Как улучшить код и реализовать паралелизм - PullRequest
0 голосов
/ 24 марта 2020

Я новичок в python и специалист по аналитике. Я сделал код, который работает и отвечает моим потребностям, за исключением времени выполнения. Это слишком медленно. Я пытался реализовать параллелизм, но безуспешно. Может ли кто-нибудь мне помочь?

И если кто-то терпелив, я хотел бы найти более эффективным написать мой код.

Спасибо.

import requests
import json
import pandas as pd
import csv
from datetime import datetime

listaCEP = pd.read_csv (r'C:\Users\ands_araujo\python\consultaDisponibilidade\cep_1_por_estado.csv', dtype=str)
listaSKU = pd.read_csv (r'C:\Users\ands_araujo\python\consultaDisponibilidade\sku_seller.csv', dtype=str)

date = []
hour = []
inputCEP = []
inputSKU = []
outputTipoEntrega = []
outputCity = []
outputState = []
outputZipCode = []
outputTime = []
outputPrice = []
outputSemEstoque = []
headers = {
    'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
    ,'referer':'https://www.magazineluiza.com.br/iphone-xr-apple-64gb-preto-4g-tela-61-retina-camera-12mp-selfie-7mp-ios-12-proc-chip-a12/p/155556000/te/ipxr/'
}
consultas = 0
erroSKU = []
erroCEP = []
erroURL = []
errosDate = []
errosHour = []
seller = []


contador = 1
for index, a in listaCEP.iterrows():
    for index, b in listaSKU.iterrows():
        url = 'https://www.magazineluiza.com.br/produto/calculo-frete/{}/{}/{}.json'.format(a.cep,b.sku,b.seller)
        response = requests.get(url,headers=headers)
        try:
            json_data = json.loads(response.text)
            inputCEP.append(a.cep)
            inputSKU.append(b.sku)
            try:
                outputTipoEntrega.append(json_data['delivery'][0]['description'])
                outputPrice.append(json_data['delivery'][0]['price'])
                outputTime.append(json_data['delivery'][0]['time'])
                outputCity.append(json_data['address']['city'])
                outputState.append(json_data['address']['state'])
                outputZipCode.append(json_data['address']['zip_code'])
                date.append(datetime.now().strftime("%d/%m/%Y"))
                hour.append(datetime.now().strftime("%H:%M"))
                if json_data['delivery'] == {}:
                    outputSemEstoque.append('true')
                else:
                    outputSemEstoque.append('false')
            except:
                outputTipoEntrega.append('n/d')
                outputPrice.append('n/d')
                outputTime.append('n/d')
                outputCity.append('n/d')
                outputState.append('n/d')
                outputZipCode.append('n/d')
                date.append(datetime.now().strftime("%d/%m/%Y"))
                hour.append(datetime.now().strftime("%H:%M"))
                if json_data['delivery'] == {}:
                    outputSemEstoque.append('true')
                else:
                    outputSemEstoque.append('false')
        except:
            erroSKU.append(b.sku)
            erroCEP.append(a.cep)
            erroURL.append(url)
            seller.append(b.seller)
            errosDate.append(datetime.now().strftime("%d/%m/%Y"))
            errosHour.append(datetime.now().strftime("%H:%M"))
        consultas = contador
        contador = contador + 1

data = {
    'date' : date
    , 'hour' : hour
    , 'inputCEP': inputCEP
    , 'inputSKU': inputSKU
    , 'outputTipoEntrega' : outputTipoEntrega
    , 'outputCity' : outputCity
    , 'outputState' : outputState
    , 'outputZipCode' : outputZipCode
    , 'outputTime' : outputTime
    , 'outputPrice' : outputPrice
    , 'outputSemEstoque' : outputSemEstoque
}
dataError = {
    'errosDate' : errosDate
    , 'errosHour' : errosHour
    , 'erroSKU' : erroSKU
    , 'erroCEP' : erroCEP
    , 'erroURL' : erroURL
    , 'seller' : seller
}

tabelaExportacao = pd.DataFrame.from_dict(data)
tabelaExportacaoError = pd.DataFrame.from_dict(dataError)

date = datetime.now().strftime("%d_%m/-%H_%M")
tabelaExportacao.to_csv(r'C:\Users\ands_araujo\python\consultaDisponibilidade\consultaCeps-{}.csv'.format(date), index = False)
tabelaExportacaoError.to_csv(r'C:\Users\ands_araujo\python\consultaDisponibilidade\ErrorconsultaCeps-{}.csv'.format(date), index = False)

1 Ответ

0 голосов
/ 24 марта 2020

Это может помочь вам в этом. Я реорганизовал поиск предметов в функцию, которая всегда возвращает диктат. Тогда достаточно просто вычислить «задания» для этой функции и вызвать их параллельно, используя multiprocessing.

Вывод сценария достаточно многословный.

Поскольку я не ваши исходные файлы данных, это естественно dry -кодировано, поэтому могут быть ошибки.

import json
import multiprocessing
import sys
import traceback
from datetime import datetime

import pandas as pd
import requests

headers = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36",
    "referer": "https://www.magazineluiza.com.br/",
}


def get_item_data(cep, sku, seller):
    url = "https://www.magazineluiza.com.br/produto/calculo-frete/{}/{}/{}.json".format(
        cep, sku, seller
    )
    data = {"Cep": cep, "Sku": sku, "Seller": seller, "Date": datetime.now()}
    try:
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        json_data = response.json()
        data.update(
            {
                "City": json_data["address"]["city"],
                "State": json_data["address"]["state"],
                "ZipCode": json_data["address"]["zip_code"],
            }
        )
        if json_data["delivery"]:
            data.update(
                {
                    "TipoEntrega": json_data["delivery"][0]["description"],
                    "Price": json_data["delivery"][0]["price"],
                    "Time": json_data["delivery"][0]["time"],
                }
            )
    except Exception as exc:
        print(cep, sku, seller, exc, file=sys.stderr)
        data["Error"] = traceback.format_exc()
    print(json.dumps(data))
    return data


def main():
    listaCEP = pd.read_csv(r"cep_1_por_estado.csv", dtype=str)
    listaSKU = pd.read_csv(r"sku_seller.csv", dtype=str)

    jobs = []

    for index, a in listaCEP.iterrows():
        for index, b in listaSKU.iterrows():
            jobs.append((a.cep, b.sku, b.seller))

    with multiprocessing.Pool() as p:
        item_datas = p.starmap(get_item_data, jobs, chunksize=10)

    export = pd.DataFrame(item_datas)

    export.to_csv(r"consultaCeps.csv", index=False)


if __name__ == "__main__":
    main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...