LINUX.ORG.RU

Хочу научиться парсить данные

 ,


5

4

Хочу научиться парсить данные из html страниц, из списков и т. п. Например, даже элементарно выдергивать ссылки на mp3 из сохраненной страницы аудиозаписей ВК.

В какую сторону смотреть, какие маны курить, что читать?

Deleted
Ответ на: комментарий от xtraeft

У меня есть скромный самописный однострочник.

cat $1 | sed '/http:/!d; /mp3/!d;' | sed "s/.* value=\"\(.*\)\".*/\1/" | cut -c1-57

Но он глуповат, т. к. обрезает сроку по точно указанной длине. Знаний не хватает, чтобы сделать «стоп», когда в конце строки появляется «mp3».

Поэтому хочу учиться.

Deleted
()
Ответ на: комментарий от Deleted

Знаний не хватает, чтобы сделать «стоп», когда в конце строки появляется «mp3».

Читай про регулярки, для твоих задач сложные не нужны. Будешь юзать их в sed и grep, этого будет достаточно для большинства твоих задач.

xtraeft ★★☆☆
()

по вк только так придумал

1] https://vk.com/dev/audio.get 163896153 ставится id копируется вручную вывод и ставится в файл vk_source

2] cat /disk/dir/music/vk_source | grep -o 'http://[a-Z0-9./=_?-]*' >/disk/dir/music/vk_wget

3] wget -i /disk/dir/music/vk_wget -P /disk/dir/music/vk_domnload

4] cd /disk/dir/music/vk_domnload/ && i= ; ls | while read; do mv "$REPLY" $((++i))".mp3"; done

5] install python-mutagen

find -iname '*.mp3' -print0 | xargs -0 mid3iconv -eCP1251 --remove-v1

6] install easytag

7] rename files

8] mv /disk/dir/music/vk_domnload/* /disk/dir/music/mp3/

8] ls /disk/dir/music/mp3/ >>/disk/dir/music/mp3/00trak_list
dima1981
()
Последнее исправление: dima1981 (всего исправлений: 2)
Ответ на: комментарий от dima1981

Нашел тут http://www.regexr.com/

Но, как идиот, методом тыка пытаюсь:

1. Найти строки, где есть id=«audio_*» 2. Прочитать в строке место, где есть mp3 3. Обрезать строку от ^http до $mp3

Ну и так далее.

Deleted
()
Ответ на: комментарий от xtraeft

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

dima1981
()
Ответ на: комментарий от erzent

кстати, если знаком, не подскажешь кое-что? Вот пример Mechanize

require 'rubygems'
require 'mechanize'

a = Mechanize.new
a.get('http://rubyforge.org/') do |page|
  # Click the login link
  login_page = a.click(page.link_with(:text => /Log In/))

  # Submit the login form
  my_page = login_page.form_with(:action => '/account/login.php') do |f|
    f.form_loginname  = ARGV[0]
    f.form_pw         = ARGV[1]
  end.click_button
...

Как поступить когда формы содержат точку в имени? Например как в одноклассниках: fr.login и fr.password. Руби воспринимает fr как форму, а login как метод, вроде.

Deleted
()
Ответ на: комментарий от Deleted

с сырыми данными все говорят с авторизацией там немного заморочено все и получением ключа, вот если когда то изучу python то обязательно забацаю скрипт работающий на момент создания ~идеально а пока что только так же все

dima1981
()

http://www.w3.org/TR/REC-DOM-Level-1/introduction.html

В йаве даже парсер и контейнер для этих целей есть. Делаешь себе дерево и ходишь по нему туда-сюда в поисках своих данных. Но это если ты программист и тебе седов с грепами не достаточно.

nanoolinux ★★★★
()
Ответ на: комментарий от xtraeft

Кусок из общей массы.

</div><div class="audio  fl_l" id="audio178691635_290324816" onmouseover="addClass(this, 'over');" onmouseout="removeClass(this, 'over');">
  <a name="178691635_290324816"></a>
  <div class="area clear_fix" onclick="if (cur.cancelClick){ cur.cancelClick = false; return;} playAudioNew('178691635_290324816')">
    <div class="play_btn fl_l">
      <div class="play_btn_wrap"><div class="play_new" id="play178691635_290324816"></div></div>
      <input type="hidden" id="audio_info178691635_290324816" value="http://cs9-2v4.vk.me/p18/f3fb176f2c69c0.mp3?extra=8jDCz7Q49SuGbAubVo5otocJIrk-vsTqqqxGrPmEUfqr9VpwtIN0ws58tmXiVoaxw5Ljl8F0THAsUfOG-FeRXDVKDfiK5ls,393" />
    </div>
    <div class="info fl_l">
      <div class="title_wrap fl_l" onmouseover="setTitle(this);"><b><a href="/search?c[q]=%C2.%C0.%CC%EE%F6%E0%F0%F2&c[section]=audio&c[performer]=1" onclick="if (checkEvent(event)) { event.cancelBubble = true; return}; Audio.selectPerformer({from_pad: 0, event: event, name: 'В.А.Моцарт'}); return false">В.А.Моцарт</a></b> &ndash; <span class="title"><a href="" onclick="Audio.showLyrics('178691635_290324816',66436320,0); return cancelEvent(event);">Симфония 6</a> </span><span class="user" onclick="cur.cancelClick = true;"></span></div>
      <div class="actions">
        <div class="audio_remove_wrap fl_r" onmouseover="Audio.rowActive(this, 'Delete song', [9, 5, 0]);" onmouseout="Audio.rowInactive(this);" onclick="Audio.deleteAudio('178691635_290324816'); return cancelEvent(event)" id="remove178691635_290324816">
  <div class="audio_remove"></div>
</div><div class="audio_edit_wrap fl_r" onmouseover="Audio.rowActive(this, 'Edit song', [9, 5, 0]);" onmouseout="Audio.rowInactive(this);" onclick="Audio.editAudio('178691635_290324816', event);">
  <div class="audio_edit"></div>
</div>

А выдернуть нужно вот такую строку.

http://cs9-2v4.vk.me/p18/f3fb176f2c69c0.mp3
Deleted
()

sed, grep, awk

Для совсем хитрого — flex + bison.

unfo ★★★★★
()
Ответ на: комментарий от Deleted

Быстро и грязно

cat 1.txt |grep -Po '(?<=value=")http://.*\.mp3'
http://cs9-2v4.vk.me/p18/f3fb176f2c69c0.mp3

xtraeft ★★☆☆
()

А еще можно открыть для себя торренты.

Lavos ★★★★★
()

Не слушай никого. Отправляйся в книжный магазин в раздел фантастики и возьми там все книги с драконом на обложке. Всё остальное --- полумеры.

ugoday ★★★★★
()
Ответ на: комментарий от Deleted

Как поступить когда формы содержат точку в имени?

Формы или инпута? Если последнее, то используй синтаксис f['field name'] = value

Приведи конкретный пример такой формы.

theNamelessOne ★★★★★
()
Ответ на: комментарий от theNamelessOne

Приведи конкретный пример такой формы.

Например как в одноклассниках: fr.login и fr.password.

use WWW::Mechanize;
use utf8;
use open ':std', ':utf8';
my $mech = WWW::Mechanize->new();
$mech->get( 'http://m.odnoklassniki.ru' );
$mech->submit_form(
            form_number => 0,
            fields      => {'fr.login'      => 'login',
                            'fr.password'   => 'passw'});
die unless ($mech->success);
print $mech->content;

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

if    ($mech->content =~ /userMain/)                 { print "Бинго!\n"       }
elsif ($mech->content =~ /Неверный логин или пароль/){ print "Другой пароль\n"}
Буду рад если покажешь как сие на рубях, у меня не получилось.

Deleted
()
Ответ на: комментарий от Deleted
# -*- coding: utf-8 -*-
require 'mechanize'

agent = Mechanize.new
agent.get('http://m.odnoklassniki.ru') do |login_page|
  form = login_page.forms.first

  form['fr.login'] = 'login'
  form['fr.password'] = 'password'

  page = agent.submit form

  # Смотрим charset тела ответа
  # puts Mechanize::Page::meta_charset(page.body) => UTF-8
  # Тело ответа отдаётся в UTF-8, но Ruby считает, что строка в ASCII-8BIT,
  # Поэтому нужен #force_encoding, иначе получим
  # mechanize-odnoklassniki.ru:16:in `===': incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string) (Encoding::CompatibilityError)

  case page.body.force_encoding('utf-8')
  when /Неверный логин или пароль/i
    puts 'Неверный логин или пароль'
  else puts 'Bingo'
  end
end
λ desktop ruby → ruby --version
ruby 1.9.3p448 (2013-06-27 revision 41675) [x86_64-linux]
λ desktop ruby → ruby mechanize-odnoklassniki.ru
Неверный логин или пароль
λ desktop ruby → 

В более поздних версиях Ruby тоже дожно работать.

theNamelessOne ★★★★★
()
Ответ на: комментарий от Deleted

Знаний не хватает, чтобы сделать «стоп», когда в конце строки появляется «mp3».

grep -o отдает не всю строку, а только вхождение в шаблон.

Я парсил библиотеку ИФРАН такой конструкцией:

RAS="http://iph.ras.ru/elib/monogr.html" ; wget $RAS -qO - | grep -o '\.\./uplfile/.*\.pdf' | wget -B $RAS -nc -i -

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

Bagrov ★★★★★
()
Ответ на: комментарий от theNamelessOne

Чтоб не задавать идиотских вопросов в стиле: как мне распарсить контекстно-независимую грамматику конечным автоматом?

ugoday ★★★★★
()

http://scrapy.org/

Python, подробная документация, работа с файлами, проекты, консоль, веб-консоль и еще куча всего. Лучше не найдешь. /thread

anonymous
()
Ответ на: комментарий от theNamelessOne

спасибо, жаль в документации этого нет.

Deleted
()
Ответ на: комментарий от dima1981
cat /disk/dir/music/vk_wget | grep -o 'https://[a-Z0-9./=_?-]*/audios/*[a-Z0-9./=_?-]*' >/disk/dir/music/vk_wget

и да копировать если вручную то из фрейма который сгинерит обработчик когда через браузер зайдешь на страницу https://vk.com/dev/audio.get и в поле id впишешь id, а потом grep

там опять что то изменилось

dima1981
()
Ответ на: комментарий от Dantix

Нормализируешь html в xml, потом xpath.

А потом открываешь сайт с кривой версткой в котором аякс во все поля да еще и данные принимает не в json а голом html и вставляет кусками как есть, а данные которые нужно напарсить на треть раскиданы по переменным js определяемым в разных частях страницы на треть в html и на треть получаются аяксом... Вспоминаешь добрым словом лоровских «знатаков», выкидываешь по дальше xpath и идешь учить регулярки. )

TDrive ★★★★★
()
Ответ на: комментарий от xtraeft

Это значительно проще, нежели рисовать очередной велосипед, который будет по DOM-дереву шукать.

И какой может быть курл для динамической странички? Ты задолбаешься в командной строке все куки-шмуки выписывать, да еще и POST-запросы...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от xtraeft

Да любой уважающий себя сайт, где странички не статичные!

Ты заходишь по некому адресу, тебе приходит начальная форма, а дальше уже все содержимое подкачивается исходя из POST-запросов. Скажем, тот же динамически подгружаемый список: ты пролистал с десяток записей — загрузился следующий десяток. И как ты курлом это будешь скачивать?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

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

Спокойно скачаю. Как минимум так же, как это делают поисковые боты.

xtraeft ★★☆☆
()

php, xpath, xquery. Всё раскладывается на удобный к использованию формат в считанные единицы строк :)

KRoN73 ★★★★★
()
Ответ на: комментарий от Eddy_Em

Ой, да пошел ты в пень дырявый. API, по-твоему, для каких целей делают?

xtraeft ★★☆☆
()
Ответ на: комментарий от Deleted

Вот поэтому хочется изучать основы основ.

Написал бы про языки, которые знаешь. Тебе бы ответили более конкретно. А так наверное (как советовали) выше стоит посмотреть в сторону xpath.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.