• Как можно оптимизировать этот код?

    Vindicar
    @Vindicar
    RTFM!
    Для начала определи, что у тебя занимает время - скачивание, или парсинг. Подходы будут разные.
    Если хочется в лоб решать задачу - то multiprocessing в руки, даёшь дочернему процессу URL, он тебе возвращает структуру данных. Главный процесс раздаёт URLы и собирает ответы в какое-то итоговое хранилище.
    Пример работы с пулом процессов.
    Ответ написан
    Комментировать
  • Как можно оптимизировать этот код?

    fox_12
    @fox_12 Куратор тега Python
    Расставляю биты, управляю заряженными частицами
    Все не смотрел, но простыни типа:
    def get_contact(ids):
        for id in ids:
            template = f'https://etender.gov.az/api/events/{id}/contact-persons'
            try:
                response = requests.get(template, timeout=20)
                if response.status_code == 200:
                    data_list = response.json()
                    for data in data_list:
                        main_data['Full_name'].append(data.get('fullName', 'None') if data.get('fullName') else 'None')
                        main_data['Contact'].append(data.get('contact', 'None') if data.get('contact') else 'None')
                        main_data['Position'].append(data.get('position', 'None') if data.get('position') else 'None')
                        main_data['Phone_number'].append(data.get('phoneNumber', 'None') if data.get('phoneNumber') else 'None')
    
                else:
                    main_data['Full_name'].append('None')
                    main_data['Contact'].append('None')
                    main_data['Position'].append('None')
                    main_data['Phone_number'].append('None')
            except requests.Timeout:
                main_data['Full_name'].append('None')
                main_data['Contact'].append('None')
                main_data['Position'].append('None')
                main_data['Phone_number'].append('None')


    пишутся гораздо проще. Да и структуру данных я бы поправил. К примеру простыня выше заменяется более лаконичным кодом:
    main_data = []
    ...
    
    def get_contact(ids):
        for id in ids:
        	current_data = {'Full_name': 'None', 'Contact': 'None', 'Position': 'None',  'Phone_number': 'None'}
            template = f'https://etender.gov.az/api/events/{id}/contact-persons'
            try:
                response = requests.get(template, timeout=20)
                if response.status_code == 200:
                    data_list = response.json()
                    for (elem_to, elem_from) in [
                         ('Full_name', 'fullName'),
                         ('Contact', 'contact'),
                         ('Position', 'position'),
                         ('Phone_number', 'phoneNumber')
                    ]:
                    	current_data[elem_to] = data.get(elem_from, 'None')
             except requests.Timeout:
                   pass
            main_data.append(current_data)
    Ответ написан
    Комментировать
  • Почему не получается спарсить названия учебных заведений?

    Vindicar
    @Vindicar
    RTFM!
    Ты хотя бы в браузере пробовал открыть исходный код страницы (обычно Ctrl-U)?
    Это динамический сайт, там по умолчанию в body два с половиной скрипта, которые уже подтягивают остальной контент. Конечно, ты его не получишь одним запросом.
    Выясняй, какой запрос скрипты делают для получения контента, и имитируй уже его. Консоль разработчика в помощь.
    Ответ написан
    Комментировать
  • Как хранить списки в бд?

    Maksim_64
    @Maksim_64
    Data Analyst
    Если использовать реляционные базы данных то делить на таблицы и описывать связи, предварительно избавившись от списков, на уровне пандаса, переформатировав (распрямив) датафрейм, метод explode например поможет избавится от списков. В целом одна и та же информация, может быть представлена в разном виде и в реляционных бд предпочтительнее (но не обязательно) иметь простые типы данных.

    Использовать не реляционные базы данных, они больше подходят если данные имеют вложенную структуру и простым переформатированием не обойтись.

    Если тебя все устраивает и тебе удобно работать с фреймом, но хочется иметь такое представление информации только не в памяти, а на диске. Можешь использовать например сериализацию, метод для фреймаto_pickle, и соответственно read_pickle для чтения.

    По итогу, когда ты собираешься хранить данные, ты их в дальнейшем будешь извлекать и анализировать. Работать с колонкам содержащими вложенные списки, можно, но не так эффективно, как с правильно организованными данными, будь уверен, что ты хранишь в колонках вложенные списки от отсутствия альтернатив.
    Ответ написан
    Комментировать
  • Как хранить списки в бд?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Вложенные списки организуют классическую связь 1:N (одному блоку данных соответствует несколько записей из списка).
    Если эти строки списка как-то обрабатываются (поиск, фильтрация и пр.), то наиболее разумна схема с 2 таблицами и внешним ключом.
    Если же списки только сохраняются и извлекаются, без вообще какой-либо обработки, то можно использовать предложенную mxelgin схему с хранением всего списка в одном поле TEXT либо JSON в сериализованном виде.
    Ответ написан
    Комментировать
  • Как хранить данные таблицы содержащие описание множества товаров без ошибки "ValueError: All arrays must be of the same length"?

    Maksim_64
    @Maksim_64
    Data Analyst
    Все очень просто, когда ты пытаешься создать фрейм, у тебя списки разной длинны получаются. Вот код который выдаст точно такую же ошибку.
    (
        pd.DataFrame({
            'A':[1,2,3],
            'B':[100,200]
        })
    )

    А вот исправленная версия кода
    (
        pd.DataFrame({
            'A':pd.Series([1,2,3]),
            'B':pd.Series([100,200])
        })
    )
    Не достающий элемент он заполнит пропущенным значением.
    Ответ написан
    1 комментарий
  • Как достать данные из тега?

    alsolovyev
    @alsolovyev
    ¯\_(ツ)_/¯ Enjoy life, Eat well & Laugh often
    66ce38f823106833102800.png
    66ce3c46df02d322388001.png

    Ваш код работает правильно, если он должен извлекать текст из первого элемента p в элементе td class="text-center".
    Однако, если ваша цель — извлечь дату из 4 колонки, то нужно изменить селектор для поиска.

    Если использовать парсер, то я бы сделал так:
    1. Нашел бы все строки tr, которые содержат данные
    2. Для каждой строки (tr) получил бы все колонки (td)
    3. Извлек бы нужные данные (например, дату) из соответствующей колонки
    4. Сохранил бы эти данные в массиве
    5. Дальше бы уже использовал бы

    Но можно же просто отправить запрос и получить все эти данные в формате json, так не проще?
    Вот ссылка, которую можно в браузере открыть - https://etender.gov.az/api/events?EventType=2&Page...
    Обычный GET запрос отправляете и получаете:
    {
      "currentPage": 1,
      "totalPages": 173,
      "pageSize": 15,
      "itemsInPage": 15,
      "totalItems": 2591,
      "items": [
        {
          "eventId": 314749,
          "eventType": 7,
          "eventStatus": 1,
          "buyerOrganizationName": "NAXÇIVAN MUXTAR RESPUBLİKASI QAZ İSTİSMAR XİDMƏTİ",
          "eventName": "Qaz tikinti quraşdırma materialları və avadanlıqlarının satınalınması",
          "publishDate": "2024-08-27T19:50:59",
          "endDate": "2024-09-18T18:00:00",
          "hasNewVersion": false,
          "awardedParticipantName": null,
          "awardedParticipantVoen": null,
          "documentViewType": 0,
          "actualVersionId": 0,
          "privateRfxId": 93247
        }
    .....
      ]
    }
    Ответ написан
    4 комментария