Genn9508 commited on
Commit
92332b1
·
verified ·
1 Parent(s): 861be2f

Upload Shorter.py

Browse files
Files changed (1) hide show
  1. Shorter.py +286 -0
Shorter.py ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os
3
+ import time
4
+ import random # !!! Добавлен импорт модуля random !!!
5
+ import datetime # !!! Добавлен импорт модуля datetime !!!
6
+ from selenium import webdriver
7
+ from selenium.webdriver.chrome.service import Service as ChromeService
8
+ from selenium.webdriver.chrome.options import Options as ChromeOptions
9
+ from webdriver_manager.chrome import ChromeDriverManager
10
+ from selenium.webdriver.common.by import By
11
+ from selenium.webdriver.common.keys import Keys
12
+ from selenium.webdriver.support.ui import WebDriverWait
13
+ from selenium.webdriver.support import expected_conditions as EC
14
+ # from pyvirtualdisplay import Display # !!! Удален импорт Display !!!
15
+ import pandas as pd
16
+ import csv # !!! Добавлен импорт модуля csv !!!
17
+
18
+ # --- Инициализация перед циклом ---
19
+ # # Start virtual display # !!! Удалены строки, связанные с виртуальным дисплеем !!!
20
+ # print("Запуск виртуального дисплея...")
21
+ # display = Display(visible=0, size=(1920, 1080))
22
+ # display.start()
23
+ # print("Виртуальный дисплей запущен.
24
+ ")
25
+
26
+ # Настройка и инициализация WebDriver
27
+ print("Инициализация WebDriver...")
28
+ chrome_options = ChromeOptions()
29
+ chrome_options.add_argument('--headless') # !!! Убеждаемся, что headless режим включен !!!
30
+ chrome_options.add_argument('--no-sandbox')
31
+ chrome_options.add_argument('--disable-dev-shm-usage')
32
+ chrome_options.add_argument('--disable-gpu')
33
+ chrome_options.add_argument('--window-size=1920,1080')
34
+ chrome_options.binary_location = '/usr/bin/google-chrome'
35
+
36
+ service = ChromeService(ChromeDriverManager().install())
37
+ driver = webdriver.Chrome(service=service, options=chrome_options)
38
+ print("WebDriver инициализирован.
39
+ ")
40
+
41
+ # !!! alice_interface.html используется ask_alice_via_interface для внутреннего отображения ответов Алисы.
42
+ # !!! Его удаление или изменение без существенной переработки функции ask_alice_via_interface
43
+ # !!! приведет к нарушению ее работы.
44
+ # Создание HTML-интерфейса (один раз)
45
+ html_content = """
46
+ <!DOCTYPE html>
47
+ <html>
48
+ <head>
49
+ <title>Alice Interface</title>
50
+ <style>
51
+ body { font-family: Arial, sans-serif; margin: 20px; background-color: #f0f0f0; }
52
+ .container { max-width: 800px; margin: auto; background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
53
+ h1 { color: #333; text-align: center; }
54
+ #input_area { display: flex; margin-top: 20px; }
55
+ #question_input { flex-grow: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px 0 0 4px; font-size: 16px; }
56
+ #ask_button { padding: 10px 15px; background-color: #007bff; color: white; border: none; border-radius: 0 4px 4px 0; cursor: pointer; font-size: 16px; }
57
+ #ask_button:hover { background-color: #0056b3; }
58
+ #alice_response { margin-top: 20px; padding: 15px; border: 1px solid #eee; background-color: #e9ecef; border-radius: 4px; min-height: 100px; overflow-y: auto; white-space: pre-wrap; word-wrap: break-word; }
59
+ </style>
60
+ </head>
61
+ <body>
62
+ <div class="container">
63
+ <h1>Talk to Alice</h1>
64
+ <div id="input_area">
65
+ <input type="text" id="question_input" placeholder="Ask Alice a question...">
66
+ <button id="ask_button">Ask Alice</button>
67
+ </div>
68
+ <div id="alice_response">Alice's response will appear here.</div>
69
+ </div>
70
+ </body>
71
+ </html>
72
+ """
73
+
74
+ file_name = 'alice_interface.html'
75
+ with open(file_name, 'w') as f:
76
+ f.write(html_content)
77
+ print(f"HTML interface '{file_name}' создана успешно.
78
+ ")
79
+
80
+ html_file_path = os.path.abspath(file_name)
81
+
82
+ # Определение функции для взаимодействия с Алисой (один раз)
83
+ def ask_alice_via_interface(question_text):
84
+ global driver, html_file_path # Доступ к глобальным driver и html_file_path
85
+ print(f"Запрос Алисе: '{question_text}'")
86
+
87
+ time.sleep(random.uniform(2, 5)) # !!! Добавлена случайная задержка перед переходом на сайт Алисы !!!
88
+ # 1. Переходим на сайт Алисы
89
+ driver.get('https://alice.yandex.ru')
90
+ print("Переход на сайт Алисы.")
91
+
92
+ # 2. Находим поле ввода на сайте Алисы
93
+ try:
94
+ input_field = WebDriverWait(driver, 15).until(
95
+ EC.presence_of_element_located((By.CSS_SELECTOR, 'textarea'))
96
+ )
97
+ except Exception:
98
+ input_field = WebDriverWait(driver, 15).until(
99
+ EC.presence_of_element_located((By.CSS_SELECTOR, 'input[type="text"]'))
100
+ )
101
+ print("Поле ввода Алисы найдено.")
102
+
103
+ # 3. Перед отпр��вкой сообщения получаем общее количество сообщений в чате
104
+ initial_total_messages_count = len(driver.find_elements(By.CSS_SELECTOR, 'div.Message'))
105
+
106
+ time.sleep(random.uniform(1, 3)) # !!! Добавлена случайная задержка перед отправкой вопроса !!!
107
+ # 4. Отправляем вопрос Алисе
108
+ input_field.send_keys(question_text)
109
+ input_field.send_keys(Keys.ENTER)
110
+ print("Вопрос отправлен Алисе. Ожидание ответа...")
111
+
112
+ # 5. Механизм ожидания и извлечения ответа Алисы
113
+ alice_response = ""
114
+ try:
115
+ # 5.1. Ждем, пока общее количество сообщений в чате увеличится (ваш вопрос + ответ Алисы)
116
+ WebDriverWait(driver, 60).until(
117
+ lambda d: len(d.find_elements(By.CSS_SELECTOR, 'div.Message')) > initial_total_messages_count + 1
118
+ )
119
+
120
+ # 5.2. После того как общее количество сообщений увеличилось, находим элемент с z-index: 2
121
+ # Это должен быть самый свежий ответ Алисы, как было указано пользователем.
122
+ alice_response_element = WebDriverWait(driver, 10).until(
123
+ EC.presence_of_element_located((By.CSS_SELECTOR, 'div.Message[style*="z-index: 2"]'))
124
+ )
125
+
126
+ # 5.3. Ждем, пока текст в этом элементе станет достаточно длинным и стабильным
127
+ def message_has_stable_text(driver_instance, element):
128
+ current_text = element.text.strip()
129
+ word_count = len(current_text.split()) # Подсчет слов
130
+ if current_text and len(current_text) > 30: # Проверка на наличие существенного текста
131
+ if word_count <= 200: # !!! Добавлена проверка на количество слов !!!
132
+ time.sleep(random.uniform(0.5, 1.5)) # Случайная короткая задержка для проверки стабильности
133
+ stable_text = element.text.strip()
134
+ if stable_text == current_text: # Возвращаем текст, если он стабилен
135
+ return stable_text
136
+ else:
137
+ print(f"Предупреждение: Ответ Алисы слишком длинный ({word_count} слов). Максимум 200 слов.
138
+ ")
139
+ return False
140
+
141
+ alice_response = WebDriverWait(driver, 30).until(
142
+ lambda d: message_has_stable_text(d, alice_response_element)
143
+ )
144
+ if not alice_response: # Если alice_response пустой после ожидания (из-за слишком длинного ответа)
145
+ alice_response = "Ошибка: Ответ Алисы превысил допустимую длину (более 200 слов)."
146
+ print(f"Сырой ответ Алисы: {alice_response}")
147
+ time.sleep(random.uniform(3, 7)) # !!! Добавлена случайная задержка после получения ответа Алисы !!!
148
+
149
+ except Exception as e:
150
+ print(f"Не удалось дождаться или извлечь ответ Алисы: {e}")
151
+ alice_response = "Ошибка: Не удалось получить ответ от Алисы."
152
+
153
+ # 6. Возвращаемся к локальному HTML-интерфейсу
154
+ driver.get(f'file://{html_file_path}')
155
+ print("Возврат к локальному HTML-интерфейсу.")
156
+
157
+ # 7. Обновляем область отображения ответа Алисы в HTML
158
+ # Очищаем ответ для вставки в JavaScript (экранируем кавычки)
159
+ sanitized_response = alice_response.replace("'", "'").replace('
160
+ ', '<br>')
161
+ script = f"document.getElementById('alice_response').innerHTML = '{sanitized_response}';"
162
+ driver.execute_script(script)
163
+ print("Ответ Алисы отображен в HTML-интерфейсе.")
164
+
165
+ return alice_response
166
+
167
+ print("Функция 'ask_alice_via_interface' определена.
168
+ ")
169
+
170
+ # --- Бесконечный цикл для повторной проверки каждые полчаса ---
171
+ while True:
172
+ print(f"
173
+ --- Начинаем проверку и обработку в {time.ctime()} ---")
174
+
175
+ bd_file_name = 'bd.csv'
176
+
177
+ # 5. Load news articles from bd.csv
178
+ df_bd = pd.DataFrame()
179
+ try:
180
+ # Check if bd.csv exists; if not, create a dummy one with proper columns
181
+ if not os.path.exists(bd_file_name):
182
+ print(f"'{bd_file_name}' not found. Creating a dummy file with 'published' and 'short_text' columns.")
183
+ today = datetime.date.today()
184
+ yesterday = today - datetime.timedelta(days=1)
185
+ dummy_data_bd = {
186
+ 'link': ['http://example.com/dummy_news_1', 'http://example.com/dummy_news_2', 'http://example.com/old_news'],
187
+ 'full_text': [
188
+ 'Это первая фейковая новость о прорыве в технологиях. Она достаточно длинная для суммаризации.',
189
+ 'Это вторая фейковая новость об экономических тенденциях и прогнозах.',
190
+ 'Это старая новость о чем-то неактуальном, которая не должна быть суммаризирована.'
191
+ ],
192
+ 'published': [today.isoformat(), yesterday.isoformat(), (today - datetime.timedelta(days=7)).isoformat()],
193
+ 'short_text': ['', '', ''] # Initially empty
194
+ }
195
+ dummy_df_bd = pd.DataFrame(dummy_data_bd)
196
+ dummy_df_bd.to_csv(bd_file_name, index=False, sep=';', encoding='utf-8-sig', quoting=csv.QUOTE_ALL)
197
+ print(f"Dummy '{bd_file_name}' created.")
198
+
199
+ # Try multiple encodings and the new delimiter for bd.csv
200
+ encodings_to_try = ['utf-8-sig', 'windows-1251', 'utf-8']
201
+ df_bd_loaded = False
202
+ for enc in encodings_to_try:
203
+ try:
204
+ df_bd = pd.read_csv(bd_file_name, encoding=enc, sep=';')
205
+ df_bd_loaded = True
206
+ print(f"'{bd_file_name}' успешно загружен с кодировкой '{enc}' (sep=';'). Всего статей: {len(df_bd)})")
207
+ break
208
+ except (UnicodeDecodeError, pd.errors.ParserError) as read_e:
209
+ print(f"Попытка загрузки '{bd_file_name}' с кодировкой '{enc}' (sep=';') не удалась: {read_e}.")
210
+ continue
211
+
212
+ if not df_bd_loaded:
213
+ raise Exception("Не удалось загрузить bd.csv ни с одной из предложенных кодировок (sep=';').")
214
+
215
+ # Ensure 'published' column is datetime and 'short_text' is string for filtering
216
+ df_bd['published'] = pd.to_datetime(df_bd['published'], errors='coerce').dt.date
217
+ df_bd['short_text'] = df_bd['short_text'].fillna('') # Fill NaN with empty string for consistent comparison
218
+
219
+ except Exception as e:
220
+ print(f"Ошибка загрузки или обработки '{bd_file_name}': {e}. Инициализация пустого DataFrame.")
221
+ df_bd = pd.DataFrame(columns=['link', 'full_text', 'published', 'short_text']) # Ensure all columns are present
222
+
223
+ # 6. Filtering for new articles to summarize
224
+ # Articles published today or yesterday AND with empty short_text
225
+ current_date = datetime.date.today()
226
+ yesterday_date = current_date - datetime.timedelta(days=1)
227
+
228
+ articles_to_summarize = df_bd[
229
+ ((df_bd['published'] == current_date) | (df_bd['published'] == yesterday_date)) &
230
+ (df_bd['full_text'].notna()) &
231
+ (df_bd['short_text'] == '')
232
+ ].copy()
233
+
234
+ if articles_to_summarize.empty:
235
+ print("В этом цикле нет новых статей для суммаризации (опубликованы сегодня/вчера и без резюме).")
236
+ else:
237
+ print(f"Найдено {len(articles_to_summarize)} новых статей для суммаризации.")
238
+
239
+ # 8. Summarize each new article with Alice and update df_bd
240
+ for index, row in articles_to_summarize.iterrows():
241
+ original_link = row['link']
242
+ full_news_text = row['full_text']
243
+
244
+ # Construct the question for Alice with specific phrasing
245
+ question_for_alice = f'Алиса, суммаризируй новость до 3 небольших предложений (раздельно) {full_news_text}'
246
+
247
+ alice_summary = ""
248
+ try:
249
+ print(f" Summarizing: {original_link}")
250
+ alice_summary = ask_alice_via_interface(question_for_alice)
251
+ print(f" Summary received for {os.path.basename(original_link)}: {alice_summary[:100]}...") # Print first 100 chars
252
+ # Add random delay after summarization before next article
253
+ time.sleep(random.uniform(5, 10))
254
+ except Exception as e:
255
+ print(f" Error processing {original_link}: {e}")
256
+ alice_summary = "Ошибка: Не удалось получить резюме от Алисы."
257
+
258
+ # Update the original df_bd DataFrame with the new summary
259
+ df_bd.loc[index, 'short_text'] = alice_summary
260
+
261
+ # 9. Save the updated df_bd to bd.csv after processing all new articles
262
+ df_bd.to_csv(bd_file_name, index=False, sep=';', encoding='utf-8-sig', quoting=csv.QUOTE_ALL)
263
+ print(f"Успешно суммаризированы и обновлены статьи в '{bd_file_name}'.")
264
+
265
+ # 10. Pause before the next iteration
266
+ print(f"
267
+ Пауза на 30 минут до следующего цикла... (Следующий запуск в {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time() + 1800))})")
268
+ time.sleep(random.uniform(1700, 1900)) # Random delay around 30 minutes
269
+
270
+ print("Цикл суммаризации остановлен.")
271
+
272
+ # --- Окончательная очистка (выполняется при прерывании цикла) ---
273
+ print("
274
+ ## Инструкции по очистке: Закрытие WebDriver
275
+ ") # !!! Убрана ссылка на виртуальный дисплей !!!
276
+ print('Для освобождения ресурсов и правильного завершения работы Selenium WebDriver, пожалуйста, запустите следующие команды в новой ячейке кода, когда закончите все взаимодействия:
277
+ ') # !!! Убрана ссылка на виртуальный дисплей !!!
278
+ print('```python
279
+ driver.quit()
280
+ print("Selenium WebDriver закрыт.")
281
+ ```
282
+ ') # !!! Убрана ссылка на виртуальный дисплей и его остановка !!!
283
+
284
+ driver.quit()
285
+ print("Selenium WebDriver закрыт.")
286
+ # display.stop() # !!! Удалена остановка виртуального дисплея !!!