Язык Python и миллион запросов в секунду

Очень большое количество запросов в секунду.

Мне нужно разработать мобильное приложение, которое требует много запросов к базе данных. Много средств, пиковое значение может составлять 1 миллион в секунду. Я не знаю, какую базу данных использовать и какие использовать. На стороне клиента я буду использовать phonegap для android и ios, и мне также понадобится web-интерфейс для ПК.

Мои сомнения в том, что я планирую разместить систему в Интернете и использовать Google Cloud-сообщение для передачи данных пользователям.

Могут ли онлайн-хостинги обрабатывать этот трафик? Я планирую использовать php в качестве поддержки. Или питон? программное обеспечение не должно иметь большого количества вычислений, но много запросов.

И какую систему баз данных использовать? Mysql или, Google Cloud sql?

Также расскажите мне об использовании hadoop или других технологий, таких как балансировщики нагрузки.

Увеличение количества запросов в секунду

Я пытаюсь увеличить количество запросов в секунду. В настоящее время я работаю на Python 2.7 и могу получать примерно 1 запрос в секунду. Нужно ли многопоточное / многопроцессорное выполнение функции или асинхронный запуск нескольких экземпляров функции. Я понятия не имею, как заставить это работать. Пожалуйста помоги 🙂

2 ответа

Просто используйте любую асинхронную библиотеку. Я думаю, что асинхронные варианты запросов, такие как grequest , txrequests , Request- Futures и Request-Threads будут работать лучше для вас. Ниже приведен пример кода из файла readme для grequests:

Создайте набор неотправленных запросов:

Отправьте их все одновременно:

Использование или изучение других упомянутых модулей, скажем-запросов-потоков, может быть немного более сложным, особенно с Python 2

asyncio и aiohttp могут быть еще более примечательны, но, я думаю, было бы легче узнать версию уже знакомого модуля.

Многопоточность не нужна, но вы можете попробовать многопоточность или, возможно, даже лучше, многопроцессорность и посмотреть, какая из них работает лучше всего.

Вы можете сделать несколько параллельных запросов, например, используя многопоточность:

Небольшое объяснение, хотя я не эксперт по многопоточности:

1.Queue

Модуль очереди позволяет создавать новый объект очереди, который может содержать определенное количество элементов. Существуют следующие способы управления очередью:

  • get () — удаляет и возвращает элемент из очереди.
  • put () — добавляет элемент в очередь. qsize () — возвращает количество элементов, которые в данный момент находятся в очереди.
  • empty () — возвращает True, если очередь пуста; в противном случае Ложь.
  • full () — возвращает True, если очередь заполнена; в противном случае Ложь.

Из моего небольшого опыта работы с многопоточностью это полезно для контроля того, какие данные вам еще предстоит обработать. У меня были ситуации, когда потоки делали одно и то же или все выходили, кроме одного. Это помогло мне контролировать общие данные для обработки.

2.Lock

Модуль потоков, поставляемый с Python, включает простой в реализации механизм блокировки, который позволяет синхронизировать потоки. Новая блокировка создается путем вызова метода Lock() , который возвращает новую блокировку.

Примитивный замок находится в одном из двух состояний: «заблокирован» или «разблокирован». Он создан в разблокированном состоянии. У него есть два основных метода, acqu () и release (). Когда состояние разблокировано, acqu () изменяет состояние на заблокированное и немедленно возвращается. Когда состояние заблокировано, acqu () блокируется до тех пор, пока вызов release () в другом потоке не изменит его на разблокированный, затем вызов acqu () сбрасывает его в заблокированный и возвращает. Метод release () должен вызываться только в заблокированном состоянии; он изменяет состояние на разблокированное и возвращается немедленно. Если предпринята попытка снять разблокированную блокировку, то будет вызвано ThreadError.

Для более человеческого языка блокировки являются наиболее фундаментальным механизмом синхронизации, предоставляемым модулем потоков. В любое время блокировка может удерживаться одним потоком или никаким потоком вообще. Если поток пытается удержать блокировку, которая уже удерживается каким-либо другим потоком, выполнение первого потока останавливается до тех пор, пока блокировка не будет снята.

Блокировки обычно используются для синхронизации доступа к общему ресурсу. Для каждого общего ресурса создайте объект Lock. Когда вам нужно получить доступ к ресурсу, вызовите acqu для удержания блокировки (это будет ждать освобождения блокировки, если это необходимо) и вызовите release для ее снятия.

3.Thread

Чтобы реализовать новый поток с помощью модуля потоков, вы должны сделать следующее:

  • Определите новый подкласс класса Thread.
  • Переопределите метод init (self [, args]), чтобы добавить дополнительные аргументы.
  • Затем переопределите метод run (self [, args]), чтобы реализовать то, что должен делать поток при запуске.

Создав новый подкласс Thread, вы можете создать его экземпляр, а затем запустить новый поток, вызвав метод start (), который, в свою очередь, вызывает метод run (). Методы:

  • run () — метод является точкой входа для потока.
  • start () — метод запускает поток, вызывая метод run.
  • объединение ([время]) — ожидает завершения потоков.
  • isAlive () — метод проверяет, выполняется ли еще поток.
  • getName () — возвращает имя потока.
  • setName () — устанавливает имя потока.

Это действительно быстрее?

Использование одного потока:

Используя 3 темы:

Используя 5 потоков:

Почти в 4 раза быстрее для 5 потоков. И это всего лишь 5 пустышек. Вообразите для большей части данных.

Обратите внимание: я тестировал его только под python 2.7. Для python 3.x, вероятно, необходимы незначительные корректировки.

aiohttp: установить максимальное количество запросов в секунду

Как настроить максимальное количество запросов в секунду (ограничить их) на стороне клиента с помощью aiohttp?

2 Solutions collect form web for “aiohttp: установить максимальное количество запросов в секунду”

Выполнение 3 запросов в то же время классно, а 5000, однако, не так приятно. Если вы попытаетесь сделать слишком много запросов одновременно, соединения могут начать закрываться, или вы даже можете быть заблокированы с веб-сайта.

Чтобы этого избежать, вы можете использовать семафор. Это инструмент синхронизации, который можно использовать для ограничения количества сопрограмм, которые что-то делают в какой-то момент. Мы просто создадим семафор перед созданием цикла, передавая в качестве аргумента количество одновременных запросов, которые мы хотим разрешить:

Мастер Йода рекомендует:  Поведенческие факторы будут влиять на ранжирование рекламы в поиске Яндекса

тем же, но защищенным семафором:

Это обеспечит одновременное выполнение не более 5 запросов.

Поскольку v2.0, при использовании ClientSession , aiohttp автоматически ограничивает количество одновременных подключений до 100.

Вы можете изменить предел, создав свой собственный TCPConnector и передав его в ClientSession . Например, для создания клиента, ограниченного 50 одновременными запросами:

В случае, если это лучше подходит для вашего прецедента, есть также параметр limit_per_host (который по умолчанию отключен), который вы можете передать, чтобы ограничить количество одновременных подключений к одной и той же «конечной точке». В документах:

limit_per_host ( int ) – ограничение для одновременных подключений к одной и той же конечной точке. Конечные точки одинаковы, если они имеют равную (host, port, is_ssl) тройку.

Что может Python сделать за секунду?

Порой можно услышать, что Python медленный в сравнении с определёнными языками. Мы не собираемся разводить дискуссии на тему сравнения языков, а хотим посмотреть на это с другой стороны. Когда-нибудь задумывались, сколько различных операций вы можете совершить в Python всего за 1 секунду? Пройдите наш тест и узнаете!

Примечание У всех разное железо, поэтому очевидно, что приведённые здесь результаты могут отличаться от ваших, если вы решите их проверить. Поэтому ваша задача — ошибиться менее, чем в 10 раз.

Тестируемый код написан на CPython версии 2.X. Замеры проводились на современном ноутбуке с быстрым SSD и интернет-подключением.

Самый быстрый способ http запросов

Есть массив с урлами, их около 500-100штук, когда как. Необходимо выполнять get запрос, парсить отданное и сохранять то, что спарсил в MySQL на локалхосте. Все реализовал, но только синхронно. Чуется мне, что это можно сделать намного быстрее.

Подскажите, что почитать. AsyncIO? Gevent?
Python 3.4

18.01.2020, 23:49

Самый быстрый способ копирования файлов
Есть много способов копирования фалов. Например средствами Windows (FileCopy) Побайтовое чтение.

Самый быстрый способ найти min
Какой самый быстрый способ найти минимальный элемент в массиве? При переборе через foreach времени.

Какой способ рисования самый быстрый?
Вот нашел интересный код рисования на WinApi, переводил с языка С++: procedure.

Самый быстрый способ копирования файлов
Здраствуйте, хотелось бы посоветоваться, какой способ копирования файлов является самым.

Самый быстрый способ склеивания строк
Закешировал файл в строку, десериализовал данные в массив экземпляров специально созданного класса.

посылая больше запросов than1000 в секунду в питона

Я пытаюсь отправить запрос одновременно на сервер, а затем записать среднюю задержку с помощью этого кода:

Этот код работает просто отлично, но теперь я намерен отправить более 1000 запросов в секунду. Я наткнулся на этот ответ , но я не знаю , как я могу использовать grequests для моего случая. Некоторые идеи будут очень полезны.

Документация не велика , но источник. Прочитайте источник! Проверьте первые несколько строк grequests.py на GitHub :

Возвращает новый частичный объект, который при вызове будет вести себя как функ вызывается с позиционными аргументами аргом и ключевыми аргументами ключевых словами. Если больше аргументов поступает вызов, они добавляются в аргументах. Если дополнительные именованные аргументы поставляются, они расширяют и переопределить ключевые слова.

Язык Python и миллион запросов в секунду

34 просмотра

2 ответа

11 Репутация автора

Я пытаюсь увеличить количество запросов в секунду. В настоящее время я качаю python 2.7 и могу получить примерно 1 запрос в секунду. Нужно ли мне многопоточно / мультипроцессить функцию или асинхронно запускать несколько экземпляров функции. Я понятия не имею, как это сделать. Пожалуйста помоги 🙂

Ответы (2)

1 плюс

1270 Репутация автора

Просто используйте любую асинхронную библиотеку, такую ​​как grequest, которая представляет собой асинхронную версию запросов https://github.com/kennethreitz/grequests

Создайте набор неотправленных запросов:

rs = (grequests.get (u) для u в URL-адресах)

Отправляйте их одновременно:

многопоточность является ненужным, но вы можете попробовать mutithreding и / или multiptrocessing и посмотреть, что лучше всего работает.

Автор: Serge Размещён: 31.10.2020 02:56

1 плюс

397 Репутация автора

Вы можете выполнять несколько параллельных запросов, например, используя многопоточность:

Небольшое объяснение, хотя я не специалист по многопоточности:

1.Queue

Модуль Queue позволяет создать новый объект очереди, который может содержать определенное количество элементов. Для управления очередью существуют следующие методы:

  • get () — удаляет и возвращает элемент из очереди.
  • put () — добавляет элемент в очередь. qsize () — возвращает количество элементов, находящихся в очереди.
  • empty () — возвращает значение True, если очередь пуста; иначе, False.
  • full () — возвращает True, если очередь заполнена; иначе, False.

Для моего небольшого опыта многопоточности это полезно для контроля того, какие данные вы еще должны обрабатывать. У меня были ситуации, когда потоки делали то же самое или все выходили за исключением одного. Это помогло мне управлять общими данными для обработки.

2.Lock

Модуль потоковой передачи, поставляемый с Python, включает в себя простой механизм блокировки, который позволяет синхронизировать потоки. Новая блокировка создается путем вызова Lock() метода, который возвращает новую блокировку.

Примитивный замок находится в одном из двух состояний, «заблокирован» или «разблокирован». Он создается в незаблокированном состоянии. Он имеет два основных метода: get () и release (). Когда состояние разблокировано, приобретается () изменяет состояние на заблокированное и немедленно возвращается. Когда состояние заблокировано, закрепите () блоки до тех пор, пока вызов release () в другом потоке не изменит его на разблокировку, затем вызов gets () сбрасывает его на блокировку и возвращает. Метод release () следует вызывать только в заблокированном состоянии; он изменяет состояние на разблокировку и немедленно возвращается. Если будет предпринята попытка освободить блокировку блокировки, будет поднят ThreadError.

К более человеческим языковым замкам относятся самые фундаментальные механизмы синхронизации, предоставляемые модулем потоковой передачи. В любой момент блокировка может удерживаться одним потоком или вообще нитью. Если поток пытается удерживать блокировку, которая уже удерживается каким-то другим потоком, выполнение первого потока приостанавливается до тех пор, пока блокировка не будет отпущена.

Мастер Йода рекомендует:  Сервис Яндекс.Фотки скоро закрывается

Замки обычно используются для синхронизации доступа к общему ресурсу. Для каждого общего ресурса создайте объект Lock. Когда вам нужно получить доступ к ресурсу, вызовите приобретать, чтобы удерживать блокировку (это будет ждать освобождения блокировки, если необходимо), и вызовите его, чтобы освободить его.

3.Thread

Чтобы реализовать новый поток с помощью модуля потоковой передачи, вам необходимо сделать следующее:

  • Определите новый подкласс класса Thread.
  • Переопределите метод init (self [, args]), чтобы добавить дополнительные аргументы.
  • Затем переопределите метод run (self [, args]) для реализации того, что должен делать поток при запуске.

Создав новый подкласс Thread, вы можете создать его экземпляр, а затем запустить новый поток, вызвав start (), который в свою очередь вызывает метод run (). Методы:

  • run () — метод является точкой входа для потока.
  • start () — метод запускает поток, вызывая метод run.
  • join ([время]) — ожидает завершения потоков.
  • isAlive () — метод проверяет, продолжает ли поток выполняться.
  • getName () — возвращает имя потока.
  • setName () — задает имя потока.

Это действительно быстрее?

Использование одного потока:

Использование 3 потоков:

Использование 5 потоков:

Почти в 4 раза быстрее для 5 потоков. И это всего лишь 5 фиктивных запросов. Представьте себе, что для большей части данных.

Обратите внимание: я тестировал его только под python 2.7. Для python, возможно, необходимы незначительные корректировки.

Google представил Grumpy, транслятор кода Python на язык Go

Компания Google открыла исходные тексты проекта Grumpy, в рамках которого развивается экспериментальный Python runtime для языка Go. Grumpy обеспечивает трансляцию кода на языке Python в представление на языке Go и позволяет бесшовно запускать оттранслированные Python-программы в runtime-окружении языка Go. Отмечается, что одной из основных целей проекта является обеспечение высокого уровня совместимости с CPython и достижение возможности применения Grumpy в качестве полноценной замены Python runtime для проектов на языке Python. Код транслятора написан на языке Python и поставляется под лицензией Apache 2.0.

Grumpy нацелен на использование в качестве прозрачной замены CPython 2.7 и позволяет решить проблемы с плохой работой CPython в условиях обработки массовых параллельных запросов. В частности, одной из поставленных перед Grumpy задач была оптимизация работы API YouTube, написанного на Python и обрабатывающего миллионы запросов в секунду. Grumpy не формирует байткод и не использует виртуальную машину. На выходе генерируется набор обычных исходных текстов на языке Go, которые затем могут быть преобразованы в машинный код при помощи штатного компилятора Go. В полученных после компиляции исходных текстах продолжают использоваться специфичные для Python структуры данных, но реализация структур оптимизирована для хорошей масштабируемости в условиях массовой параллельной обработки данных.

Grumpy избавлен от ключевой проблемы Python — глобальной блокировки интерпретатора (GIL, Global Interpreter Lock), не допускающей параллельного выполнения нескольких нитей кода. Grumpy также использует сборщик мусора Go для управления жизнью объектов вместо применяемой в Python системы на основе подсчёта ссылок. В сочетании с компиляцией в исполняемый код, подобные улучшения позволяют добиться существенного прироста производительности. Уровень масштабируемости Grumpy хорошо демонстрирует нижеприведённый график, отражающий результаты прохождения теста производительности Fibonacci:

Grumpy состоит из трёх основных компонентов:

  • grumpc — компилятор, выполняющий разбор кода на языке Python и генерацию кода на языке Go. Для разбора используется модуль ast (Abstract Syntax Trees);
  • Grumpy Runtime. Сформированный код на языке Go оперирует структурами данных, представляющими Python-объекты. Данные структуры и операции с ними определены в runtime-библиотеке grumpy, реализованной по аналогии с Python C API;
  • Стандартная библиотека Grumpy. Большинство штатных библиотек Python написаны на языке Python и без проблем работают в Grumpy. Стандартная библиотека Grumpy является незначительно модифицированной копией stdlib из состава CPython 2.7. Python-библиотеки в которых используются модули на языке Си переписаны на Python, но используют родные расширения языка Go (напрямую Grumpy не поддерживает Python C API).

Сравнение языков программирования, их быстродействия.

Дубликаты не найдены

каким раком ява быстрее си и ассемблера оказалась?

У меня есть мысля, конечно, но фиг знает, поэтому ждём других, может мысли лучше будут.

Таким, что есть задачи, для которых джава оптимизировалась, а есть другие. Вот если ты играл в майнкрафт и судишь джаву по нему — у тебя беда, гнать тебе надо на нативную LWGL, а так же на школьников с компиляторами, которые не могут писать нормально.

А у нас, к примеру, к джаву идёт до 5 миллионов запросов в секунду по сети от всей Рашки, и она нагружена только на 15-25%.

..эмм.. как то немного удивлен, по осчусчениям — хдге то что то не договаривают и сравнивают теплое с мягким. Ибо все ж bash это shell (если уж точно то Bourne again shell) со своими возможностями запуска сценариев/скриптов.

Ну а скрипт — эт некомпиленный код, в то время как продукт жизнедеятельности «мастодонтов платформ языков программирования» подлежит компиляции.

В общем и целом — в табличке не хватает ассемблера — подозреваю крайним правым столбиком ;о)

справа крайний это как раз баш. Асм идет 10 слева

10 Секунд. у Жабы 6. КАК и почему?!

jit компиляция позволяет java довольно достойно сражаться в производительности с остальными языками. тем более компиляторы любят все оптимизировать, чего не скажешь об проге на asm, где, обычно, как написал, так и работает. так что черт его знает, че она там наоптимизировала, вот и работает быстро. может оно 6 секунд грузилось и jit компилировало, а цикл вообще выкинуло нафиг)

и вообще чувак, который тестил, забавный) у него прога на асм работала 13 секунд, а на си 10. он дизассемблировал сишную прогу, посмотрел, че не так, сказал ну окей и поставил асму 10 секунд тоже)

Как использовать Python для LSI-копирайтинга

Этот термин последнее время довольно популярен в SEO-индустрии. Кто-то утверждает, что LSI-копирайтинг является залогом попадания сайта в ТОП, кто-то считает это бесполезной тратой времени и ресурсов.

Давайте немного разберемся, что же такое LSI и как оно связано с SEO?

Мастер Йода рекомендует:  Создание CSS-анимации при помощи Move.js

Если совсем коротко и грубо, это один из математических подходов к анализу текстов, разработанный в конце 1980-х годов для повышения точности извлечения информации. По сути, он находит скрытые связи между словами, чтобы улучшить понимание информации.

В теории, если поисковик может понять контент, он будет корректно его индексировать и ранжировать по целевым запросам. Использование синонимов и тематических слов также теоретически может усилить значимость общей части контента, что должно быть хорошо для SEO, верно? К огромному сожалению, нет прямых доказательств, подтверждающих это.

LSI-копирайтинг – довольно успешный маркетинговый ход. Теперь мы пишем не просто SEO-тексты, а LSI-тексты. Окей. Суть та же. Мы просто добавим синонимов.

Однако не все так плохо. Подобные анализы текстов позволяют сделать достаточно выводов, чтобы создать действительно полезный контент.

Благодаря тем замечательным людям, которые создают библиотеки, используемые в различных языках программирования, мы можем довольно быстро строить терм-документные матрицы, высчитывать TF-IDF и прочее. Если кому-то интересно, пишите в комментариях, я опишу, как это можно сделать на том же Python.

В этой статье не будем уходить в столь глубокий анализ. Относительно понятную картину контента, который ранжируется поисковиками, дает анализ N-грамм, встречающихся в текстах сайтов ТОПа и запросов Вордстат.

Ниже представлен код, написанный на Python 3.0.

Собственно, начнем с подключения того, что давно сделали за нас – импортируем библиотеки, которые понадобятся для работы:

На мой взгляд, pymorphy2 – пока лучшее, что придумано для работы с русскоязычными текстами. Именно эта библиотека дает наиболее точные результаты при работе с словоформами. Именно поэтому скрипт написан на Python.

После импорта вводим ключевик, для которого будем искать тематические слова и словосочетания. Возьмем для примера «очки виртуальной реальности».

Первое, что делаем – получаем данные Вордстат. Для этого нам нужно зарегистрировать свое приложение для API Яндекс.Директа и получить токен. С Директом все несколько сложнее, чем с другими API, т.к. необходимо подавать заявку на доступ приложения и ждать, пока ее подтвердят на стороне Яндекса.

Прописываем полученный токен:

Создаем запрос на формирование отчета к API и получаем в ответе id нашего отчета:

Дадим Яндексу время на формирование отчета:

В идеале нужно отправлять еще один запрос, ответом на который будет статус отчета, но, как показывает практика, 10 секунд вполне достаточно, чтобы сформировать этот отчет.

Теперь нам нужно получить сам отчет. Подставляем в свойство param наш id и обращаемся к API.

В итоге нам нужно сформировать два датафрейма, где один отвечает за столбец в Вордстат «Что искали со словом…» (SearchedWith), а второй – за похожие запросы (SearchedAlso).

API Директа отдает нам всего 300 запросов, то есть 6 страниц в разделе SearchedWith, то есть нужно учитывать, что это лишь часть запросов.

Теперь переходим к основной задаче – небольшому анализу текстов.

Для этого нам необходимо обратиться к XML выдаче Яндекса. После всех необходимых настроек переходим в раздел «Тест» и выставляем следующие параметры.

Чтобы сильно не перегружать систему, возьмем для анализа ТОП 50 вместо максимально доступного ТОП 100.

Под этим блоком формируется URL самой XML выдачи. Копируем его и подставляем в него наш декодированный запрос.

Прописываем путь к файлу, в которые запишутся все URL ТОП 50 выдачи по нашему запросу. Такой способ вывода результатов позволит в дальнейшем как иметь список URL, так и удалять из списка те, которые отдают ошибку при попытке достать оттуда информацию. Как правило, это случается крайне редко, но имеет место быть.

Отправляем запрос и парсим XML выдачу:

Прописываем путь к файлу, куда запишем весь текст, полученный при парсинге страниц:

Парсим полученные URL и записываем контент тега p результаты в один файл. Тут нужна небольшая, но важная оговорка, что далеко не на всех сайтах текст оформляется тегами p, а некоторые в эти теги добавляют совершенно левую информацию. Но при анализе довольно большого объема текстов хватает информации, которую мы получаем таким образом. В конце концов перед нами не стоит задача создания точной терм-документной матрицы. Нам лишь нужно найти наиболее часто употребляемые N-граммы в текстах ТОП 50.

Приступаем к анализу полученных данных. Указываем файл, куда запишем результаты, загружаем данные парсинга и список стоп-слов, которые мы хотим исключить из анализа N-грамм (предлоги, союзы, технические и коммерческие слова и т.д.)

А дальше немного магии: приводим все слова к их исходной форме, настраиваем CountVectorizer на подсчет N-грамм с количеством слов от 2 до 4 и записываем результат в файл.

Все, что нужно дальше, – записать все результаты в один Excel-файл:

На первом листе выводим подсчет N-грамм, используемых в контенте сайтов:

Быстрый взгляд на первые 100 N-грамм позволяет нам отобрать следующие: «угол» «обзор», «oculus rift», «шлем виртуальный реальность», «vr box», «gear vr», «диагональ дисплей», «playstation vr», «vr очки», «виртуальный мир», «3d очки», «пульт управление», «100 градусов», «полный погружение», «совместимость ос android», «датчик приближение», «линза устройства», «vr гарнитур», «дополнить реальности». Это дает понять, что в тексте стоит затронуть такие понятия, как «угол обзора», «полное погружение», «линзы», «дополненная реальность», «датчик приближения», рассмотреть вопросы совместимости, использовать такие синонимы, как «шлем виртуальной реальности», «vr» и т.д.

На втором листе – данные Вордстат по похожим запросам (по сути, N-Граммы отобразили схожую картину, но порой тут можно встретить то, что в текстах замечено не было):

На третьем, собственно, 300 запросов из первого столбца Вордстат:

Таким образом, мы получаем небольшую памятку для копирайтера или для самих себя, которая упростит составление ТЗ на написание текста по заданной тематике и даст понятия, которые необходимо раскрыть при написании контента.

Подводя итоги, хочется сказать: чтобы не попасть в это самое «очко виртуальной реальности», важно понимать, что наличие LSI-запросов в тексте не является гарантом нахождения статьи в ТОПе. Нужно изучить тексты на хотя бы нескольких сайтах самостоятельно, помнить про основы оптимизации любой статьи, грамотно ее оформлять, размечать и проводить еще много-много работы для того, чтобы создавать понятный и полезный контент как для поисковика, так и для пользователя.

Добавить комментарий