Как спарсить скачать и обработать много текста (sed, iconv)

октября 22, 2013 , , , 0 Comments

sed обработать много текста
Как то мне пришлось столкнутся с довольно не стандартной задачей. Мне понадобилось скачать, а затем обработать большой текстовый фаил. Задача заключалась в том чтобы полученный в последствии текст нужно было очистить от знаков препинания и мусора, а так же полностью удалить английский текст, оставив только русский. Далее необходимо было получить только уникальные слова из полученного текста. Я решил описать весь проделанный процесс от начала и до конца.




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

# mkdir -p ~/Scripts/Books
# nano ~/Scripts/bookdwnload.sh



Делаем наш скрипт executable
# chmod +x ~/Scripts/bookdwnload.sh

И запускаем его (осторожно траффик)
# cd ~/Scripts/Books && ./bookdwnload.sh &

Начнется парсинг url на прямые ссылки до txt фаилов, а затем их скачивание. Процесс довольно долгий, поэтому если вам не хочется скачивать весь раздел, то измените параметр for page in {1..1015}, в данный момент он берет все страницы от 1 до 1015 той.

После скачивания у нас будет очень много фаилов ~25 тысяч. Прочтем все их сожержимое в 1 фаил, чтобы было удобнее, а остальные фаилы удалим. На момент написания статьи весь скачанный раздел занимал 5gb текста.

# cd ~/Scripts/Books && cat *.txt >> ~/Scripts/bigfile.txt && rm -rf ~/Scripts/Books


Кодировка текста


Полученный на первом этапе фаил необходимо перевести в правильную кодировку, перед работой с ним. Посмотрим его кодировку с помощью enca (если у вас нет этой программы то установить ее не составит труда на любом дистрибутиве) Забегая вперед сразу скажу что полученный фаил имеет кодировку windows-1251
# enca bigfile.txt

Так как мы хотим избавится от ненужных символов, нам придется сначала перевести фаил в нужную кодировку с помощью iconv, но тут сразу сталкиваемся с проблемой. Дело в том, что для этого в процессе обработки фаила - iconv будет полностью загружать весь фаил в оперативную память, а ее ведь может и не хватить, поэтому cначала придется разбить большой фаил на части, каждую из которых мы переведем в UTF-8, а затем снова прочтем результат в 1 большой фаил.

# split -a 1 -d -b 700M bigfile.txt kusok.txt.part && rm -rf bigfile.txt

Таким образом мы получили несколько фаилов по 700mb и удалили большой фаил. Теперь поочередно изменим кодировку в каждом фаиле на UTF-8 а так же удалим иcходный фаил(чтобы не мешал)

# nice -10 iconv -c -f WINDOWS-1251 -t UTF-8 kusok.txt.part0 >> part0.txt && rm -rf kusok.txt.part0
# nice -10 iconv -c -f WINDOWS-1251 -t UTF-8 kusok.txt.part1 >> part1.txt && rm -rf kusok.txt.part1
# nice -10 iconv -c -f WINDOWS-1251 -t UTF-8 kusok.txt.part2 >> part2.txt && rm -rf kusok.txt.part2

и так далее пока не преобразуем все фаилы. Обратите внимание что размер наших фаилов стал больше, когда мы перевели его в UTF-8. Иногда бывает сразу несколько разных кодировок в 1 фаиле и iconv выдает ошибку связанную с тем, что не может распознать символ, именно поэтому мы используем iconv с ключем -c что означает что такие символы будут пропущены.

Теперь, прочтем содержимое всех фаилов в 1 фаил и удалим ненужные
# cat *.txt >> utf-bigfile.txt && rm -rf part*.txt

Ну вот мы и подошли к самой интересной части.


Обработка текста


Теперь можем приступать к обработке большого фаила.

Не смотря на то, что мы скачали раздел русской литературы, там все равно присутствуют английские книги, а так же английский текст, поэтому уберем все символы кроме русских, а так же оставим пробелы между словами:
# nice -10 sed -i -e 's/[^а-яА-Я\ ]\+//g;s/\ \{2,\}/\ /g' utf-bigfile.txt

Убираем пробелы в начале строки
# nice -10 sed -i 's/^ *//g' utf-bigfile.txt

Убираем все пустые строчки
# nice -10 sed -i '/./!d' utf-bigfile.txt

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

Теперь просто заменяем пробел(ы) на перенос строки
# nice -10 sed -i -e 's/ /\n/g' utf-bigfile.txt

Приводим все слова к нижнему регистру
# nice -10 sed -i 's/[[:upper:]]/\l&/g' otjim.txt

Сортируем все по уникальности, оставит только по 1 уникальному слову
# nice -10 cat otjim.txt | sort -u >> base.txt


Таким образом мы получили только уникальные слова, содержащиеся в 25 тысячах книг. Полученный из книг фаил изначально занимал 5gb, после перевода его в UTF-8 увеличился почти в 2 раза, а после всех проделанных действий превратился в фаил с уникальными словами, занимающий 66mb. Надеюсь было интересно, кстати все это лучше проделать с базой данных данных. Изначальная задача по получению уникальных словосочетаний из уникальных слов была решена - конец.

0 коммент.: