Я использую библиотеку Scrapy, чтобы почистить сайт, где люди продают автомобили.
Я использую функции Python и IBM Cloud и Scrapy для достижения этой цели. Идея состоит в том, чтобы ежедневно очищать сайт с помощью действий IBM Cloud и добавлять каждое транспортное средство в таблицу vehicles
в базе данных Postgres. Эта часть отлично работает.
Структура таблицы vehicles
выглядит следующим образом:
На первом шаге в таблицу vehicles
добавлено все, кроме столбца данных (данные об автомобиле, которые необходимо добавить на втором шаге). Это отлично работает.
Второй шаг - каждый день проверять каждый добавленный автомобиль из таблицы vehicles
, существует ли он на сайте (его можно удалить или продать). На этом шаге я добавляю каждое зацикленное транспортное средство к таблице daily_run_vehicle
. Структура daily_run_vehicle
выглядит следующим образом:
Если автомобиль существует, я очищаю детали и обновляю таблицу vehicles
, столбец data
и устанавливаю для столбца handled
значение ИСТИНА в таблице daily_run_vehicle
. Если он продан или удален, то я увеличиваю столбец retries
в таблице daily_run_vehicle
.
Второй шаг должен выполняться каждый день.
Сначала я перебираю каждое транспортное средство из vehicles
, для которого столбец handled
в таблице daily_run_vehicle
не равен ИСТИНА или если handled
имеет значение Ложь, но число retries
равно 5 или более. И для каждой итерации я добавляю новую запись в таблицу daily_run_vehicle
.
Действие prepare-get-vehicles
и код следующий:
import json
import requests
from common.db import add_logs, get_vehicle_references
from common.db import capture_error
from common.common import APIHOST, NAMESPACE, USER_PASS
def execute_reference(reference, reference_url):
action = "prepare-get-vehicle"
url = APIHOST + "/api/v1/namespaces/" + NAMESPACE + "/actions/" + action
response = requests.post(url,
data=json.dumps({"reference": reference, 'reference_url': reference_url}),
params={"blocking": "false"},
auth=(USER_PASS[0], USER_PASS[1]),
headers={"Content-Type": "application/json"})
print(response.json())
def main(params):
try:
for reference in get_vehicle_references():
execute_reference(reference[0], reference[1])
return {"Success": "prepare-get-vehicles action executed successfully."}
except Exception as e:
capture_error(str(e))
return {"Failure": "prepare-get-vehicles action NOT executed successfully."}
Функция get_vehicle_references
выглядит следующим образом:
def get_vehicle_references():
conn = db_connection()
cur = conn.cursor()
try:
s = "SELECT reference, reference_url FROM vehicles v WHERE (NOT EXISTS (select reference from daily_run_vehicle WHERE (handled = %s or (handled = %s and retries >= %s)) AND reference = v.reference))"
cur.execute(s, (True, False, 5))
return cur.fetchall()
except Exception as e:
capture_error(str(e))
conn.close()
prepare-get-vehicle
действие ничего не делает, кроме добавления новой записи в таблицу daily_run_vehicle
, и оно выглядит следующим образом:
def main(params):
try:
insert_daily_run_vehicle(params.get("reference", None), params.get("reference_url", None))
return {"Success.": "The DB filler (daily_run_vehicle) is successfully executed."}
except Exception as e:
capture_error(str(e))
return {"Failure": "The DB filler (daily_run_vehicle) action NOT executed successfully."}
Но проблема в том, что таблица vehicles
содержит более 300 тыс. Записей, и она с каждым днем становится все больше и больше. Чем цикл for в действии prepare-get-vehicles
занимает много времени для выполнения в IBM Cloud. Время ожидания 600 с, но цикл for занимает намного больше времени.
Любой совет, как мне решить мою проблему и как я могу перебрать таблицу, содержащую более 300 тыс. Записей, и для каждой записи добавить новую строку в daily_run_table
?
Заранее спасибо.