Skip to content

[BUG]: объявления помечаются просмотренными до записи в файл — при сбое данные теряются #300

@denyWhite

Description

@denyWhite

ОС

Macos 26.4.1

Версия парсера

v3.2.14

Способ запуска

Python (venv)

Текст ошибки

При парсинге нескольких страниц по одной ссылке существует состояние гонки между записью в SQLite и записью в файл.         
                                                                                                                                                                                                                                                                                                                   
Объявления помечаются как просмотренные в БД **внутри** цикла по страницам, хранение в файл происходит **после** завершения всего цикла.                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                                                   
  ## Код                                                                                                                                                                                                                                                                                                           
   
  `parser_cls.py`, метод `parse()`:                                                                                                                                                                                                                                                                                
                                                            
  
  # строка ~181 — внутри цикла по страницам
  if filter_ads:                                                                                                                                                                                                                                                                                                   
      self.__save_viewed(ads=filter_ads)   # SQLite: помечаем сразу
      ads_in_link.extend(filter_ads)       # только копим в памяти                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                                                   
  # строка ~187 — после цикла
  if ads_in_link:                                                                                                                                                                                                                                                                                                  
      self.result_storage.save(ads_in_link)  # файл: пишем только если цикл дошёл до конца
                                                                                                                                                                                                                                                                                                                   
  Сценарий воспроизведения
                                                                                                                                                                                                                                                                                                                   
  1. Настроить парсинг нескольких страниц (count > 1)                                                                                                                                                                                                                                                              
  2. Страница 1 обработана успешно — объявления помечены просмотренными
  3. На странице 2 происходит необработанное исключение (например, в fetch_api_data,                                                                                                                                                                                                                               
  нотификаторе, или любом другом месте без try/except)                                                                                                                                                                                                                                                             
  4. Исключение всплывает из parse(), ads_in_link теряется                                                                                                                                                                                                                                                         
  5. result_storage.save() не вызывается                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                   
  Результат: объявления со страницы 1 помечены просмотренными в БД, но не записаны в файл. При следующем запуске они будут отфильтрованы фильтром is_viewed и не попадут в файл никогда.                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                   
  Предлагаемое исправление                                                                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                                                                                                   
  Перенести result_storage.save() внутрь цикла, рядом с __save_viewed():                                                                                                                                                                                                                                           
   
  if filter_ads:                                                                                                                                                                                                                                                                                                   
      self.__save_viewed(ads=filter_ads)                    
      self.result_storage.save(filter_ads)  # сохраняем сразу, а не копим
      ads_in_link.extend(filter_ads)                                                                                                                                                                                                                                                                               
   
  Тогда запись в файл и пометка в БД происходят атомарно для каждой страницы.

Логи

-

Конфиг

[avito]
tg_token = ""
tg_chat_id = []
vk_token = ""
vk_user_id = []
urls = []
count = 100
keys_word_white_list = []
keys_word_black_list = []
seller_black_list = []
max_price = 99999999
min_price = 0
geo = ""
proxy_string = ""
proxy_change_url = ""
pause_general = 43200
pause_between_links = 5
max_age = 0
max_count_of_retry = 5
ignore_reserv = true
ignore_promotion = false
one_time_start = false
one_file_for_link = true
parse_views = false
save_xlsx = false
save_json = true
use_webdriver = false
use_bypass_api = true
cookies_api_key = "ыап"
use_own_cookies = false
parse_phone = false
proxy_notifier = ""
tg_only_text = false
retry_delay = 5
timeout = 20
block_threshold = 3

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions