пошук валідних URLs для текстового змісту
import os
import re
import requests
from bs4 import BeautifulSoup
import time
import concurrent.futures
from urllib.parse import urlparse, quote
import random
def is_valid_url(url):
"""Перевірка валідності та доступності URL."""
try:
parsed_url = urlparse(url)
if not all([parsed_url.scheme, parsed_url.netloc]):
return False
response = requests.head(url, timeout=5, allow_redirects=True)
return response.status_code < 400
except Exception as e:
print(f"Помилка перевірки URL {url}: {str(e)}")
return False
def extract_text_from_file(file_path):
"""Витяг тексту з файлу."""
try:
with open(file_path, 'r', encoding='utf-8') as file:
return file.read()
except UnicodeDecodeError:
try:
with open(file_path, 'r', encoding='latin-1') as file:
return file.read()
except Exception as e:
print(f"Помилка читання файлу {file_path}: {e}")
return ""
except Exception as e:
print(f"Помилка читання файлу {file_path}: {e}")
return ""
def extract_keywords(text, max_keywords=5):
"""Витяг ключових слів з тексту."""
words = re.findall(r'\b[А-Яа-яA-Za-z]{4,}\b', text.lower())
stop_words = {'the', 'and', 'are', 'for', 'not', 'but', 'was', 'you', 'this', 'that',
'have', 'with', 'from', 'they', 'will', 'would', 'could', 'should',
'what', 'when', 'where', 'which', 'there', 'their', 'about',
'це', 'та', 'але', 'як', 'що', 'для', 'він', 'вона', 'вони', 'був', 'була', 'були',
'цей', 'ця', 'ці', 'той', 'та', 'ті', 'мій', 'моя', 'мої', 'твій', 'твоя', 'твої',
'наш', 'наша', 'наші', 'ваш', 'ваша', 'ваші'}
filtered_words = [word for word in words if word not in stop_words]
if not filtered_words:
return []
from collections import Counter
return [word for word, _ in Counter(filtered_words).most_common(max_keywords)]
def search_web_resources(text, max_results=15):
"""Пошук веб-ресурсів за текстом."""
keywords = extract_keywords(text)
if not keywords:
print("Не знайдено ключових слів.")
return []
query = ' '.join(keywords)
print(f"Пошук: {query}")
all_links = []
try:
ddg_links = search_duckduckgo(query, max_results)
all_links.extend(ddg_links)
if len(all_links) < max_results:
google_links = search_google(query, max_results - len(all_links))
all_links.extend(google_links)
if len(all_links) < max_results:
bing_links = search_bing(query, max_results - len(all_links))
all_links.extend(bing_links)
seen = set()
unique_links = [x for x in all_links if not (x in seen or seen.add(x))]
return unique_links[:max_results]
except Exception as e:
print(f"Помилка пошуку: {e}")
return []
def get_random_user_agent():
"""Повертає випадковий user agent."""
user_agents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36 Edg/90.0.818.66'
]
return random.choice(user_agents)
def search_duckduckgo(query, max_results=15):
"""Пошук за допомогою DuckDuckGo."""
encoded_query = quote(query)
search_url = f"https://html.duckduckgo.com/html/?q={encoded_query}"
headers = {
'User-Agent': get_random_user_agent(),
'Accept': 'text/html,application/xhtml+xml,application/xml',
'Accept-Language': 'uk-UA,uk;q=0.9,en-US;q=0.8,en;q=0.7', # Пріоритет української мови
'Referer': 'https://duckduckgo.com/'
}
try:
response = requests.get(search_url, headers=headers, timeout=10)
if response.status_code != 200:
print(f"Помилка пошуку DuckDuckGo: {response.status_code}")
return []
soup = BeautifulSoup(response.text, 'html.parser')
links = []
for result in soup.find_all('a', class_='result__url'):
href = result.get('href')
if href and href.startswith('http'):
links.append(href)
if not links:
for a in soup.find_all('a'):
href = a.get('href')
if href and href.startswith(('http://', 'https://')) and not any(domain in href for domain in ['duckduckgo.com', '.ppt', '.pptx', '.pdf', '.doc', '.docx']):
links.append(href)
print(f"Знайдено {len(links)} посилань DuckDuckGo.")
return links[:max_results]
except Exception as e:
print(f"Помилка DuckDuckGo: {e}")
return []
def search_google(query, max_results=15):
"""Пошук за допомогою Google."""
encoded_query = quote(query)
search_url = f"https://www.google.com/search?q={encoded_query}"
headers = {
'User-Agent': get_random_user_agent(),
'Accept': 'text/html,application/xhtml+xml,application/xml',
'Accept-Language': 'uk-UA,uk;q=0.9,en-US;q=0.8,en;q=0.7' # Пріоритет української мови
}
try:
response = requests.get(search_url, headers=headers, timeout=10)
if response.status_code != 200:
print(f"Помилка пошуку Google: {response.status_code}")
return []
soup = BeautifulSoup(response.text, 'html.parser')
links = []
for div in soup.find_all('div', class_='yuRUbf'): a_tags = div.find_all('a')
for a in a_tags:
if a.get('href') and a['href'].startswith('http'):
links.append(a['href'])
if not links:
for a in soup.find_all('a', href=True):
href = a['href']
if '/url?q=' in href:
actual_url = href.split('/url?q=')[1].split('&')[0]
if not any(domain in actual_url for domain in ['google.com', 'gstatic.com', '.ppt', '.pptx', '.pdf', '.doc', '.docx']):
links.append(actual_url)
if not links:
for a in soup.find_all('a', href=True):
href = a['href']
if href.startswith(('http://', 'https://')) and not any(domain in href for domain in ['google.com', 'gstatic.com', '.ppt', '.pptx', '.pdf', '.doc', '.docx']):
links.append(href)
print(f"Знайдено {len(links)} посилань Google.")
return links[:max_results]
except Exception as e:
print(f"Помилка Google: {e}")
return []
def search_bing(query, max_results=15):
"""Пошук за допомогою Bing."""
encoded_query = quote(query)
search_url = f"https://www.bing.com/search?q={encoded_query}"
headers = {
'User-Agent': get_random_user_agent(),
'Accept': 'text/html,application/xhtml+xml,application/xml',
'Accept-Language': 'uk-UA,uk;q=0.9,en-US;q=0.8,en;q=0.7' # Пріоритет української мови
}
try:
response = requests.get(search_url, headers=headers, timeout=10)
if response.status_code != 200:
print(f"Помилка пошуку Bing: {response.status_code}")
return []
soup = BeautifulSoup(response.text, 'html.parser')
links = []
for li in soup.find_all('li', class_='b_algo'):
a_tag = li.find('a')
if a_tag and a_tag.get('href'):
href = a_tag['href']
if href.startswith(('http://', 'https://')) and not any(domain in href for domain in ['bing.com', 'microsoft.com', '.ppt', '.pptx', '.pdf', '.doc', '.docx']):
links.append(href)
if not links:
for a in soup.find_all('a', href=True):
href = a['href']
if href.startswith(('http://', 'https://')) and not any(domain in href for domain in ['bing.com', 'microsoft.com', '.ppt', '.pptx', '.pdf', '.doc', '.docx']):
links.append(href)
print(f"Знайдено {len(links)} посилань Bing.")
return links[:max_results]
except Exception as e:
print(f"Помилка Bing: {e}")
return []
def process_file(file_path, output_dir):
"""Обробка файлу та збереження веб-ресурсів."""
try:
base_name = os.path.basename(file_path)
text = extract_text_from_file(file_path)
if not text:
print(f"Не знайдено тексту у файлі {file_path}")
return
print(f"Обробка файлу: {base_name}...")
resources = search_web_resources(text)
if not resources:
print(f"Не знайдено ресурсів для {base_name}")
return
print(f"Знайдено {len(resources)} ресурсів, перевірка валідності...")
valid_urls = []
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
future_to_url = {executor.submit(is_valid_url, url): url for url in resources}
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
try:
if future.result():
valid_urls.append(url)
print(f"✓ Валідний URL: {url}")
else:
print(f"✗ Невалідний URL: {url}")
except Exception as e:
print(f"Помилка перевірки URL {url}: {e}")
if valid_urls:
output_file = os.path.join(output_dir, f"links_{base_name}")
with open(output_file, 'w', encoding='utf-8') as f:
for url in valid_urls:
f.write(f"{url}\n")
print(f"Збережено {len(valid_urls)} валідних URL у {output_file}")
else:
print(f"Не знайдено валідних URL для {base_name}")
except Exception as e:
print(f"Помилка обробки файлу {file_path}: {e}")
def main():
folder_path = input("Введіть шлях до папки з файлами: ").strip()
if not os.path.isdir(folder_path):
print(f"Помилка: {folder_path} не є коректною директорією.")
return
output_dir = os.path.join(folder_path, "links_notes")
if not os.path.exists(output_dir):
os.makedirs(output_dir)
print(f"Створено директорію: {output_dir}")
for filename in os.listdir(folder_path):
file_path = os.path.join(folder_path, filename)
if os.path.isfile(file_path) and not filename.startswith('.') and not os.path.basename(file_path).startswith('links_'):
process_file(file_path, output_dir)
time.sleep(random.uniform(2, 5))
print("Обробку завершено!")