CoderCastrov logo
CoderCastrov
Парсер

Парсинг веб-страниц с помощью bash

Парсинг веб-страниц с помощью bash
просмотров
4 мин чтение
#Парсер
Table Of Content

    Это легально?

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


    Когда и почему использовать bash?

    Хорошие инструменты для парсинга веб-страниц платные. Если веб-сайт имеет достаточно простую HTML-структуру, вы можете легко использовать curl для выполнения запроса и затем извлечь нужные значения с помощью команд bash, таких как grep, cut, sed, ...

    Как это сделать

    Откройте веб-страницу, которую вы хотите спарсить, и затем просмотрите исходный код страницы.

    Попробуйте найти в HTML-коде значения, которые вы хотите извлечь. Некоторые значения будут легко получить, потому что они находятся в определенном именованном теге, но другие - нет. Давайте рассмотрим несколько примеров.

    // выполнение запроса curl и сохранение содержимого в tmp_file
    **curl page.htm > tmp_file**// Все нижеперечисленные команды будут иметь результат "The content i want"// Простой тег (внутри других тегов)
    // <ul class="list"><li class="specific_class"><span>The content i want</span></li><div>...**cat tmp_file | grep "class=\"specific_class\"" | cut -d'>' -f4 | cut -d'<' -f1**
    // Содержимое внутри тега meta
    // <meta property="specific_property" content="The content i want"/>**cat tmp_file | grep specific_property | cut -d'"' -f4**// Если тег, который вы хотите получить, встречается несколько раз в выводе
    // <ul class="list"><li class="specific_class"><span>The content i want</span></li><div>...
    // <h1 class="specific_class">I don't want this</h1>
    // Если вы хотите получить первое вхождение - используйте grep -m1
    **cat tmp_file | grep -m1 "class=\"specific_class\"" | cut -d'>' -f4 | cut -d'<' -f1**// Если вы не знаете, какое это вхождение - попробуйте использовать grep по другому признаку
    **cat tmp_file | grep "class=\"specific_class\"" | grep span | cut -d'>' -f4 | cut -d'<' -f1**// Если тег и значение не находятся в одной строке
    // <h1 class="specific_class">
    // The content i want
    // </h1>
    **cat tmp_file | grep -A1 "class=\"specific_class\"" | tail -1**// Если тег и значение не находятся в одной строке, а содержимое разделено на строки
    // <h1 class="specific_class">
    // The content
    // i want
    // </h1>
    **cat tmp_file | grep -A2 "class=\"specific_class\"" | tail -2 | sed 'N;s/\n/ /'**

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

    // Предполагая, что на веб-сайте есть 20 страниц
    n="1"
    while [ $n -lt 20 ]
    do
      curl "page.htm?pag=$n" > tmp_file
      ...
      n=$[$n+1]
    done

    Давайте рассмотрим полный пример и скрипт для извлечения нужной информации.

    Мы хотим извлечь информацию о всех книгах, имеющихся на веб-сайте https://www.ebookslist.htm. Предположим, что каждую книгу можно получить с помощью параметра book, и всего их 100.

    Часть HTML-кода, содержащая нужную нам информацию:

    <ul class="list"><li class="title"><span>The Subtle Art of Not Giving a F*ck</span></li><div>...
    <meta property="date_added" content="16/04/2017"/>
    <ul class="list"><li class="price"><span>EUR 18</span></li><div>...
    <h1 class="shipping">Free shipping</h1>
    <h1 class="author">
    Mark Manson and Roger Wayne
    </h1>
    <h1 class="description">
    #1 New York Times Bestseller Over 2 million copies sold In this generation-defining self-help guide, a superstar blogger cuts through the crap to show us how to stop trying to be "positive" all the time so that we can truly become better, happier people.
    For decades, we've been told that positive thinking is the key to a happy, rich life. "F**k positivity," Mark Manson says.
    </h1>

    Мы хотим получить CSV-файл со следующими данными: "Дата;Название;Автор;Описание;Цена;Доставка" (я выбрал ';' в качестве разделителя, потому что в тексте могут встречаться ',').

    #!/bin/bashn="1"
    rm -f tmp_file extractData.csv// записываем заголовки в CSV-файл
    echo "Дата;Название;Автор;Описание;Цена;Доставка" > extractData.csvwhile [ $n -lt 100]
    do
      // выполняем curl и сохраняем результат в tmp_file
      curl "https://www.ebookslist.htm?book=$n" > tmp_file
      
      // увеличиваем "book"
      n=$[$n+1]  // получаем дату
      date=$(cat tmp_file | grep date_added | cut -d'"' -f4)  // получаем название
      title=$(cat tmp_file |grep "class=\"title\"" | cut -d'>' -f4 | cut -d'<' -f1)  // получаем автора
      author=$(cat tmp_file |grep -A1 "class=\"author\"" | tail -1)  // получаем описание
      desc=$(cat tmp_file |grep -A2 "class=\"description\"" | tail -2 | sed 'N;s/\n/ /')
      
      // получаем цену
      price=$(cat tmp_file |grep "class=\"price\"" | grep span | cut -d'>' -f4 | cut -d'<' -f1)  // получаем информацию о доставке
      ship=$(cat tmp_file |grep "class=\"shipping\"" | cut -d'>' -f2 | cut -d'<' -f1)  // записываем данные о книге в CSV-файл
      echo "$date;$title;$author;$desc;$price;$ship" >> extractData.csvdone

    Результат CSV для примера HTML:

    Дата;Название;Автор;Описание;Цена;Доставка
    16/04/2017;The Subtle Art of Not Giving a F*ck;Mark Manson and Roger Wayne;#1 New York Times Bestseller Over 2 million copies sold In this generation-defining self-help guide, a superstar blogger cuts through the crap to show us how to stop trying to be "positive" all the time so that we can truly become better, happier people. For decades, we've been told that positive thinking is the key to a happy, rich life. "F**k positivity," Mark Manson says.;EUR 18;Free shipping

    Важно: если вы получаете ошибку "illegal byte sequence" (чаще всего это происходит при использовании sed), добавьте следующее в свой скрипт

    export LC_CTYPE=C
    export LANG=C