Работа с текстом. Уникализация текста по средством C#

guloc

Client
Регистрация
12.09.2016
Сообщения
178
Благодарностей
108
Баллы
43
Всем привет, Обычно я писал статьи про уязвимости Яндекса, но сейчас решил написать про работу с текстом и уникализацию текста по средством c#.
Данная статья поможет в создании своих дорвеев, каких то проектов связанных с текстом и тд.
Для меня стала актуальна данная тема так как создание сайтов дело не дешёвое, а статьи всё дороже и дороже. Конечно сделать полностью уникальную статью и читабельную ни кому ещё не удавалось, хотя в последнее время расплодилось множество нейросетей, возможно в будущем и появится, что то достойное. Но пока делаем то что можем.
Данная статья больше призвана в помощи работы с текстом и его удобному изменению.

chrome_2019-12-12_14-37-07.png


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

Идеи для контента:
1. Парсим субтитры (такой шаб с обработкой и правкой есть если что обращайтесь)
2. Перевод
3. Копипаст (с дальнейшей обработкой)
4. Вопросы и ответы с сервиса вопросы майл и яндекс знатоки и аналогичные сервисы (сбиваем шингл)

Ниже приведу различные снипеты и их реализацию в проектах.
1. К примеру нам надо удалить ненужные слова из текста и брать мы будем эти слова из списка

C#:
string text1 = project.Variables["tekst"].Value; //переменная

var list = project.Lists["Bad_Words"];//список

             //  string[] Bad_Words = project.Lists["Bad_Words"].;
          
                   for(int i=0;i < list.Count;i++)
                    {
                        string bad = list[i];
                      
                        //if (Bad_Words[i] != null && Bad_Words[i] != "" && Bad_Words[i] != " ")
                        {
                            text1 = text1.Replace(bad, ""); //и при нахождении Bad_Word замена его на пусто.
                        }
                    }
                  
return text1;
Снипет берёт из списка слова и удаляет эти слова из переменной в которой уже находится текст для обработки. Подходит для избавления от мусорных слов.

2. Далее мы хотим заменить слова, снипет ниже берёт к примеру каждое 3-е слово и если есть такое слово в тексте то заменяет его. Регулировать слова можно в настройках.

C#:
string text1 = project.Variables["tekst"].Value; //переменная

var list = project.Lists["Replace_Words"];//список с ключами
Random rnd1 = new Random();

string[] ArrayText = text1.Split(' ');

text1 = "";

for (int j = 0; j < ArrayText.Length-1; j++)
{
    if (j % int.Parse(project.Variables["NumberReplaceWord"].Value) == 0) //переменная от куда будет браться номер слова, чтобы он не все слова заменял к примеру а каждое 3-е
    {
        bool setWord=false;
      
        for (int i = 0; i < list.Count; i++)
        {
            string lst = list[i];

            string[] ArrayWords = lst.Split('|');

            if(ArrayText[j].IndexOf(ArrayWords[0])!=-1)
            {
                text1 += ArrayText[j].Replace(ArrayWords[0],ArrayWords[rnd1.Next(1, ArrayWords.Length)]) + " ";
                setWord = true;
                break;
            }
        }
      
        if(!setWord)
        {
            text1 += ArrayText[j] + " "; 
        }
    }
    else
    {
        text1 += ArrayText[j] + " ";
    }
}

text1 += ArrayText[ArrayText.Length - 1];

return text1;
Формат слов в списке должен быть такой - слово замены|на что заменем1|на что заменяем 2
Снипет берёт рандомное значение и заменяет слово

3. Мы хотим добавить сео ключ перед определённым знаком, в случае того что статья не особо оптимизирована под запросы, делаем как написано ниже:
C#:
string paragraph = ""; // Исходная строка текста

string text = project.Variables["tekst"].Value; //переменная от куда берётся текст

IZennoList Keys_List = project.Lists["Keys_List"]; //список, где хранятся ключи
string key = ""; // Исходная строка ключа
Random rnd = new Random(); // Новая случайность
int Keys_List_Count = Keys_List.Count; // узнаем количество строк списка

// Преобразуем строку в массив с разделением по точка + пробел
string[] array = text.Split(new[] { ". " }, StringSplitOptions.RemoveEmptyEntries);

// Проходим получившийся массив в цикле
for (int i = 0; i < array.Length; i++)
{
    // Если последняя строка, то прервываем цикл
    if (i >= array.Length - 1)
    {
        paragraph += array[i];
        break;
    
    }
    else
    {
        paragraph += array[i];
    
        // Если CountForkey элемент массива == текущему, то добавляем ключ перед новым абзацем
        if ((i + 1) % int.Parse(project.Variables["CountForkey"].Value) == 0) //переменная, где хранится число, после которого ставить ключ
        {// указываем через переменную после какой точки вставлять ключ
            // но сначала берем случайных ключ из списка:
            int IndexRand = rnd.Next(0,Keys_List_Count); // ищем случайный номер в пределах количества строк списка
            key = Keys_List[IndexRand];    // берем строку по этому номеру (случайную)   
            paragraph += " " + key;
        }
    
        paragraph += ". ";
    }
}
return paragraph;
4. Также нам нужно разбить текст сео заголовками делаем вот так:
C#:
string paragraph = ""; // Исходная строка текста

string text = project.Variables["tekst"].Value; //переменная от куда берётся текст

IZennoList Keys_List = project.Lists["Заголовки"]; //список, где хранятся ключи
string key = ""; // Исходная строка ключа
Random rnd = new Random(); // Новая случайность
int Keys_List_Count = Keys_List.Count; // узнаем количество строк списка

// Преобразуем строку в массив с разделением по точка + пробел
string[] array = text.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);

// Проходим получившийся массив в цикле
for (int i = 0; i < array.Length; i++)
{
    // Если последняя строка, то прервываем цикл
    if (i >= array.Length - 1)
    {
        paragraph += array[i];
        break;
    
    }
    else
    {
        paragraph += array[i];
           paragraph += ".";
    
      // Если CountForHeadline элемент массива == текущему, то добавляем заголовок перед новым абзацем
if ((i + 1) % int.Parse(project.Variables["CountForHeadline"].Value) == 0) //переменная, где хранится число, после которого ставить заголовок
{// указываем через переменную после какой точки вставлять заголовок


            // но сначала берем случайных ключ из списка:
            int IndexRand = rnd.Next(0,Keys_List_Count); // ищем случайный номер в пределах количества строк списка
            key = Keys_List[IndexRand];    // берем строку по этому номеру (случайную)   
           paragraph += Environment.NewLine;
paragraph += key;
paragraph += Environment.NewLine;
        }
    
    
    }
}
return paragraph;
Он берёт случайный заголовок и ставит его после определённой точки. Данный метод тоже помогает нам повысить «сеошность» текста

5. Следующий снипет поможет Нам поставить абзац после определённой точки, чтобы наш текст не был сплошной простынёй, а разбит для удобства чтения:

C#:
string paragraph = "";
// Исходная строка текста
string text = project.Variables["tekst"].Value;
// Преобразуем строку в массив с разделением по точка + пробел
string[] array = text.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
// Проходим получившийся массив в цикле
for (int i = 0; i < array.Length; i++) {

    // Если последняя строка, то прервываем цикл
    if (i >= array.Length-1) {
        paragraph += array[i];
        break;
    } else
        paragraph += array[i] + "."; 

    // Если 5 элемент массива, то добавляем два переноса строки (т.е. новый абзац)
    if ((i+1) % int.Parse(project.Variables["tochka"].Value) == 0)
        paragraph += Environment.NewLine;
    else
        paragraph += " ";
    string int_test = project.Lists["test"].First();
}
// Возвращаем отформатированный по абзацам текст
return paragraph;
6. Хорошо к примеру мы уникализировали текст, но если текст без знаков препинания. Для поисковиков это знак того что текст сгенерирован, давайте используем правила русского Языка и сделаем массовую замену. Взял часть из своего шаблона.

C#:
var dictionary = new Dictionary<string, string>()
{
      {" что ", ", что "},
      {" а ", ", а "},
    {" это ", " - это "},
    {" где ", " где, "},
    {" наверное ", " наверное, "},
    {" чтобы ", ", чтобы "},
    {" конечно ", " конечно, "},
    {" к счастью ", " к счастью, "},
    {" во первых ", " во-первых, "},
    {" кстати ", " кстати, "},
    {" представьте себе ", " представьте себе, "},
    {" между прочим ", " между прочим, "},
    {" увы ", ". Увы "},
    {" но ", " но, "},
    {" зато ", " зато, "},
    {" интересный ", " интересный, "},
     {" если ", " если "},
     {" хотя ", ", хотя "},
     {" так как ", ", так как "},
     {" куда ", ", куда "},
     {" откуда ", ", откуда "},
{" не точно ", " не точно, "},
{" более того ", " более того, "},
{" мы начинаем ", " мы начинаем, "},
{" значит ", " значит, "},
{" правильно формулировать ", " правильно формулировать. "},
{" рекомендации ", " рекомендации. "},
{" так вот ", " так вот, "},
{" ну это ", ". Ну это "},
{" всем привет", " Всем привет! "},
{" бинаре ", " вэбинаре, "},
{" как ", ", как "},
{" далее ", " далее, "},
{" новичков ", " новичков. "},
{" начнем с начала ", " начнем с начала. "},
{" любой компании ", " любой компании. "},
{" направлений бизнеса ", " направлений бизнеса. "},
{" проще с вами общаться ", " проще с вами общаться. "},
{" это нужно ", " это нужно, "},
{" постановках целей ", " постановках целей. "},
{" округлим ", " округлим, "},
{" мы нашли ", " мы нашли, "},
{" просто ", ", просто "},
{" их мечту ", " их мечту. "},
{" после ", ", после "},
{" зачем ", " зачем, "},
{" подать заявку ", " подать заявку. "},
{" обратите внимание ", " обратите внимание, "},
{" кто ", ", кто "},
{"подпишитесь на канал", ""},
{"поставьте лайк", ""},
{" год подряд ", " год подряд, "},
{" если вдруг ", " если вдруг, "},
{" от вас денег ", " от вас денег, "},
{" в чем ", ", в чем "},
{" чуть чуть ", " чуть-чуть "},
{" Yes ", "Yes,"},
{" about ", "about,"},
{" No ", "No,"},
};


string text = project.ExecuteMacro(project.Variables["tekst"].Value);

foreach(var item in dictionary)   
{
    text = Macros.TextProcessing.Replace(text, item.Key, item.Value, "Text", "All");   
}

project.Variables["tekst"].Value = text;
7. Отлично запятые ну и другие замены мы можем проставить сами, а как же точки ведь есть огромное количество фраз которые нужно заменить. В этом случае мы не сможем предугадать где нужно ставить точку, даже поисковые сети пока не могут это воссоздать так как любой язык многогранен и логику построения фраз не всегда удаётся проследить. В таком случаем мы воспользуемся снипетом где мы сможем добавить точки в определённом порядке.

C#:
string text = project.Variables["tekst"].Value;//переменная где текст
int numReplace = Convert.ToInt32(project.Variables["probel"].Value);// рандомное число с точкой
var aText = text.Split(' ');
string newText = "";
int i = 1;
foreach(string str in aText){
    if(i == numReplace){
        newText += str+"^ ";
        i = 0;
    }else
        newText += str+" ";
    i++;
}

return newText.Replace("^", ".");;
8. Закидываем данный снипет в переменную и обрабатываем его следующим кодом, который сделает большую букву после каждой точки.
C#:
string str = project.Variables["tekst"].Value;//Переменная с текстом в нижнем регистре
        {
            string[] s = Regex.Split(str, @"(?<=[\. |\! |\? ]+\ )");
            for (int i = 0; i < s.Length; i++)
            {
                    if (s[i].Length > 1)
                         s[i] = s[i].Substring(0, 1).ToUpper() + s[i].Substring(1, s[i].Length - 1);
                    else s[i] = s[i].ToUpper();
                      
            }
       project.Variables["tekst"].Value = string.Join("", s);
        }
Таким образом мы сможем добавить точки в текст после определённого пробела, будет не так подозрительно со стороны пс. По другому хз как решить.
9. Также можно разбить текст по абзацам с помощью этого регулярного выражения:
C#:
(.*?\.){{-Random.Int-|-2-|-5-}}
10. И можно разбить каждое предложение с новой строки
C#:
[А-ЯA-Z].{15,}?(\.|\!|\?)(?=\ |\r|\n|$)
Такими методами можно повысить уникальность текста, конечно это не идеальный текст но для дорвеев и автонаполняемых порталов самое то. Буду рад если кто то поделится какими то своими решениями для уникализации или предоставит лучше код чем здесь. Так как тема для меня сейчас актуальна, да и не только для меня.
 
Категория
Полезно

Вложения

Последнее редактирование модератором:

Valandersi

Client
Регистрация
19.01.2015
Сообщения
1 206
Благодарностей
529
Баллы
113
Можно пару примеров текстов на входе и выходе?
 
  • Спасибо
Реакции: Nats1 и vadimlgg2

DenisK

Client
Регистрация
28.06.2016
Сообщения
363
Благодарностей
151
Баллы
43
Спасибо за статью, решения пригодятся.
 
  • Спасибо
Реакции: guloc

deskuznetsov

Client
Регистрация
29.08.2019
Сообщения
267
Благодарностей
107
Баллы
43
Спасибо! Пригодится материал, как раз сейчас тема актуальна и думал писать свой начитать синонимайзер, а то платить надоело)
 
  • Спасибо
Реакции: guloc

Pro-100

Client
Регистрация
23.06.2018
Сообщения
11
Благодарностей
2
Баллы
3
Спасибо ТС, очень информативно и полезно!
 
  • Спасибо
Реакции: guloc

Range8Hero

Client
Регистрация
02.06.2017
Сообщения
82
Благодарностей
10
Баллы
8
а есть какое нибудь api на русском ?
 

Astraport

Client
Регистрация
01.05.2015
Сообщения
3 521
Благодарностей
2 531
Баллы
113
  • Спасибо
Реакции: Range8Hero

boris.lyashuk

Client
Регистрация
07.07.2018
Сообщения
18
Благодарностей
0
Баллы
1
Кто то опробовал снипет 2 по замене слов?
Работает таким образом?
Исходный текст Пароход плывет по реке
После замены Туманоход плывет по реке
Берет не все слово целиком а любое совпадение?
 

boris.lyashuk

Client
Регистрация
07.07.2018
Сообщения
18
Благодарностей
0
Баллы
1
Уникализация текста по средством C#
Как сделать что бы бралось точное вхождение слова?

string text1 = project.Variables["tekst"].Value; //переменная

var list = project.Lists["Replace_Words"];//список с ключами
Random rnd1 = new Random();

string[] ArrayText = text1.Split(' ');

text1 = "";

for (int j = 0; j < ArrayText.Length-1; j++)
{
if (j % int.Parse(project.Variables["NumberReplaceWord"].Value) == 0) //переменная от куда будет браться номер слова, чтобы он не все слова заменял к примеру а каждое 3-е
{
bool setWord=false;

for (int i = 0; i < list.Count; i++)
{
string lst = list;

string[] ArrayWords = lst.Split('|');

if(ArrayText[j].IndexOf(ArrayWords[0])!=-1)
{
text1 += ArrayText[j].Replace(ArrayWords[0],ArrayWords[rnd1.Next(1, ArrayWords.Length)]) + " ";
setWord = true;
break;
}
}

if(!setWord)
{
text1 += ArrayText[j] + " ";
}
}
else
{
text1 += ArrayText[j] + " ";
}
}

text1 += ArrayText[ArrayText.Length - 1];

return text1;



Формат слов в списке должен быть такой - слово замены|на что заменем1|на что заменяем 2


 

artur23

Client
Регистрация
14.04.2014
Сообщения
143
Благодарностей
4
Баллы
18
ну работа с сервисом каким нибудь по уникализации текста через api
https://sinoni.men/ - есть такой, но у меня так post запрос и не заработал... почему-то - вопрос к создателям зеннопостер. Хотя разработчик прислал код - через онлайн сервис post запросов - все работает...
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)