Поисковик слов на страницах сайта. Нужна помощь в оптимизации кода
Всем привет. Захотел написать скрипт, который будет брать список сайтов, заходить на каждый, смотреть первую страницу и искать на ней какие-то нужные мне слова, и если найдет, то добавлять эти сайты в список результатов
Есть 2 проблемы и 2 вопроса:
На сколь угодно значимом размере этого списка (скажем, 100+ сайтов и 20+ слов) код работает медленно. Какие есть варианты ускорить процесс?
Т.к. я ищу в текстовом представлении страницы, то могут найтись значения, находящиеся внутри тегов, что мне совсем не нужно. Искать нужно только среди текста, представленного непосредственно на странице, а этих слов может среди них не оказаться. Как можно настроить поиск нужным мне способом?
Ниже сам код:
import requests
import re
masks = ['раскраск', 'game', 'играть', 'детск', 'кроссворд']
# result_2 = []
checked = 0
errors = 0
with open('websites.txt', 'r') as websites, open('result.txt', 'w') as result:
for site in websites:
if 'youtube' in site.lower():
continue
try:
page = requests.get(site.strip())
except:
errors += 1
continue
if any(mask in page.text for mask in masks):
checked += 1
# print(site.strip())
result.write(site.strip() + '\n')
print('Проверено сайтов: ', checked)
print('Ошибок: ', errors)
Пример файла с сайтами по Ссылке
И бонусный, более общий вопрос. Возможно существует более эффективный способ определить тематику сайта?
Ответы (1 шт):
Реализовал ваш алгоритм, код полностью по новому переписал.
Алгоритм многопоточный, 20 потоков задал, внутри ThreadPool(20), у меня для вашего входного websites.txt файла отработало за несколько секунд. Для парсинга и поска в HTML использовал BeautifulSoup.
Для использования кода нужно установить некоторые PIP модули через python -m pip install requests bs4 lxml.
Входные слова я вначале конвертирую в регулярные выражения через re.compile() так что можно в качестве слов любые регулярки использовать.
Результатом алгоритма является выходной websites.res.json, в нём для каждого сайта указано true/false (найдено/не-найдено) либо строка с сообщением об ошибке. Выход может быть не сортирован, т.к. я обрабатываю сайты для быстроты не в строгом порядке.
import multiprocessing.pool, requests, bs4, lxml, re, json
words = ['раскраск', 'game', 'играть', 'детск', 'кроссворд']
words = [re.compile(w) for w in words]
with open('websites.txt', 'r', encoding = 'utf-8') as f:
urls = [line.strip() for line in f if line.strip()]
def Match(url):
try:
text = requests.get(url).text
soup = bs4.BeautifulSoup(text, 'lxml')
for word in words:
if len(soup(text = word)) > 0:
return url, True
return url, False
except Exception as ex:
return url, str(ex)
finally:
print('.', end = '', flush = True)
with multiprocessing.pool.ThreadPool(20) as pool:
d = dict(list(pool.imap_unordered(Match, urls)))
with open('websites.res.json', 'w', encoding = 'utf-8') as f:
f.write(json.dumps(d, indent = 4))
Вход (websites.txt):
http://zentut.info
http://avito.ru
http://killernews.ru
http://znanija.org
http://trashbox.ru
http://makefrag.ru
http://mybuses.ru
http://otzovik.com
http://scanword.org
http://witchhut.com
http://fortnitefun.ru
http://russian7.ru
http://skazkiwsem.ru
http://stolica-s.su
http://ukrtvory.ru
http://yesasia.ru
http://allforchildren.ru
http://allcalc.ru
http://ampproject.org
http://braintos.com
http://bugaga.ru
http://calc.ru
http://canlidizihd8.com
http://c-cafe.ru
http://classes.ru
http://comboplayer.ru
http://deadsouls.ru
http://fanfics.me
Выход (websites.res.json):
{
"http://otzovik.com": false,
"http://scanword.org": true,
"http://fortnitefun.ru": true,
"http://ukrtvory.ru": false,
"http://russian7.ru": false,
"http://witchhut.com": true,
"http://braintos.com": true,
"http://c-cafe.ru": true,
"http://deadsouls.ru": false,
"http://mybuses.ru": false,
"http://allcalc.ru": false,
"http://killernews.ru": false,
"http://canlidizihd8.com": false,
"http://bugaga.ru": false,
"http://classes.ru": false,
"http://makefrag.ru": true,
"http://fanfics.me": false,
"http://zentut.info": false,
"http://stolica-s.su": true,
"http://comboplayer.ru": false,
"http://avito.ru": false,
"http://yesasia.ru": false,
"http://ampproject.org": false,
"http://calc.ru": true,
"http://skazkiwsem.ru": true,
"http://allforchildren.ru": true,
"http://trashbox.ru": true,
"http://znanija.org": false
}