Содержание

Пишем php парсер сайтов с нуля

Опубликовано: 13.02.2015 12:48

Просмотров: 65120

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

Парсер на php — раз плюнуть!

Приветствую вас, наши дорогие читатели. Сегодня решил написать сложную статью про парсеры (сбор информации со сторонних ресурсов).

Скажу сразу, что вам потребуется знание основ программирования на php. В противном случае почитайте теории. Я не буду рассказывать азы, а сразу полезу показывать всё на практике.

Шаг 1 — PHP Simple HTML DOM Parser

Для парсинга сайтов мы будем использовать простецкую библиотечку под названием PHP Simple HTML DOM Parser, которую вы сможете скачать на сайте разработчика. Данный класс поможет вам работать с DOM-моделью страницы (дерево документа). Т.е. главная идея нашей будущей программы будет состоять из следующих пунктов:

  1. Скачиваем нужную страницу сайта
  2. Разбираем её по элементы (div, table, img и прочее)
  3. В соответствии с логикой получим определённые данные.

Давайте же начнём написание нашего php парсера сайтов.

Для начала подключим нашу библиотеку с помощью следующей строки кода:

include 'simple_html_dom.php';

Шаг 2 — Скачиваем страничку

На этом этапе мы смогли подключить файл к проекту и теперь пришла пора скачать страничку для парсинга.

В нашей библе есть две функции для получения удалённой страницы сайта. Вот эти функции

  1. str_get_htm() — получает в качестве параметров обычную строку. Это полезно, если вы стянули страничку с помощью CURL или метода file_get_contents. Пример использования: 
    $seo = str_get_html('<html>Привет, наш любимый читатель блога SEO-Love.ru!</html>')

     

  2. file_get_html() — здесь же мы передаём в качестве параметра какой-то url, с которого нам потребуется скачать контент. 
  3. $seo = file_get_html('http://www.site.ru/');

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

$seo = file_get_html('http://www.site.ru/');
$seo->clear();

Шаг 3 — Ищем нужные элементы на странице

После получения DOM-модели мы можем приступить непосредственно к поиску нужного элемента-блока в полученном коде.

Большая часть функций поиска использует метод find(selector, [index]). Если не указывать индекс, то функция возвратит массив всех полученных элементов. В противном случае метод вернёт элемент с номером [index].

 Давайте же приведу вам первый пример. Спарсим мою страничку и найдём все картинки.

1

2

3

4

5

6

7

8

9

10

11

12

//подключили библиотеку
require_once 'simple_html_dom.php';
//скачали страничку
$page = file_get_html('http://xdan.ru');
//проверка нашли ли хотя бы 1 блок img и не пустая ли страница
if($page->innertext!='' and count($data->find('img'))){
  //для всех элементов найдём элементы img
  foreach($data->find('img') as $img){
    //выведем данный элемент
    echo $a->innertext;
  }
}

 

Если что-то пошло не так, то прошу отписаться в комментариях. Здесь очень кстати будет мой предыдущий материал Запутываем PHP-код без зазрения совести. Полезно для тех, кто программирует как ниндзя. Больше не отвлекаюсь, идём дальше.

Шаг 4 — Параметры поиска

Надеюсь все уже поняли, что в метод find() можно писать как теги (‘a’), так и id’шники (‘#id’), классы (‘.myclass’), комбинации из предыдущих элементов (‘div #id1 span .class’). Таким образом вы сможете найти любой элемент на странице.

Если метод поиска ничего не найдёт, то он возвратит пустой массив, который приведёт к конфликту. Для этого надо указывать проверку с помощью фукнции count(), которую я использовал выше в примере.

Также вы можете производить поиск по наличию атрибутов у искомого элемента. Пример:

//Найдём все изображения с шириной 300
$seo->find('img[width=300px]');
//Найдём изображения, у которых задана ширина
$seo->find('img[width]');
//Поиск по наличию нескольких классов
$seo->find('img[class=class1 class2]');//<img class="aclass1 class2"/>
//Ищем несколько тегов вместе
$seo->find('div, span, img, a');
//Поиск по вложенности.
//В div ищем все спаны, а в спанах ссылки
$html->find('div span a');

Замечу, что у каждого вложенного тега так же есть возможность поиска!

Есть много вариантов поиска по атрибутам. Перечислять не стану, для более полного руководства прошу пройти на сайт разработчиков 🙂

Обычный текст, без тегов и прочего, можно искать так find(‘text’). Комментарии аналогично find(‘comment’).

Шаг 5 — Поля элементов

Каждый найденный элемент имеет несколько структур:

  1. $seo->tag   Прочитает или запишет имя тега искомого элемента.
  2. $seo->outertext   Прочитает или запишет всю HTML-структуру элемента с ним включительно.
  3. $seo->innertext   Прочитает или запишет внутреннюю HTML-структуру элемента.
  4. $seo->plaintext   Прочитает или запишет обычный текст в элементе. Запись в данное поле ничего не поменяет, хоть возможность изменения как бы присутствует.

Примеры:

$seo = str_get_html("<div>first word <b>second word</b></div>");
echo $seo; // получим <div>first word <b>second word</b></div>, т.е. всю структуру
$div = $seo->find("div", 0);
echo $div->tag; // Вернет: "div"
echo $div->outertext; // Получим <div>first word <b>second word</b></div>
echo $div->innertext; // Получим first word <b>second word</b>
echo $div->plaintext; // Получим first word second word 

Эта возможность очень просто позволяет бегать по DOM-дереву и перебирать его в зависимости от ваших нужд.

Если вы захотите затереть какой-либо элемент из дерева, то просто обнулить значение outertext, т.е. $div->outertext = «»; Можно поэксперементировать с удалением элементов.

P.S. Я обнаружил проблему с кодировками при очистке и всяческими манипуляциями с полем innertext. Пришлось использовать outertext и затем с помощью функции strip_tags удалял ненужные теги.

Шаг 6 — Дочерние элементы

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

  1. $seo->children ( [int $index] )   Возвращает N-ый дочерний элемент, иначе возвращает массив, состоящий из всех дочерних элементов.
  2. $seo->parent()   Возвращает родительский элемент искомого элемента.
  3. $seo->first_child()   Возвращает первый дочерний элемент искомого элемента, или NULL, если результат пустой
  4. $seo->last_child()   Возвращает последний дочерний элемент искомого элемента, или null, если результат пустой
  5. $seo->next_sibling()   Возвращает следующий родственный элемент искомого элемента, или null, если результат пустой
  6. $seo->prev_sibling()   Возвращает предыдущий родственный элемент искомого элемента, или null, если результат пустой

 Я особо не пользовался этими возможностями, потому что они ещё ни разу не пригодились мне. Хотя один раз при разборе таблицы использовал, потому что они структурированы, что делает разбор очень простым и лёгким.

Шаг 7 — Практика

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

public function parser_rock_txt() {
        $i = 0;
        $new_songs = 0;
        //номер категории, чтобы хранить в базе. У меня Рок = 1
        $category = 1;
  		//Скачиваем страничку с сайта Rock-Txt.ru
        $data = file_get_html('http://rock-txt.ru/');
        //нашли хотя бы одну ссылку на песни по буквам (проходим навигацию)
        if (count($data->find('div.a-z a'))) {
            //пробежим по всей навигации
            foreach ($data->find('div.a-z a') as $a) {
                //Выводим букву, которую парсим
                echo ('Текущая буква - ' . $a->plaintext . '<br />');
                //нашли список всех исполнителей
                $data_vocalist = file_get_html("http://rock-txt.ru" . $a->href);
                //если есть хотя бы один исполнитель
                if (count($data_vocalist->find('#dle-content div.full-news a'))) {
                    foreach ($data_vocalist->find('#dle-content div.full-news a') as $vocalist) {
                        //приводим название исполнителя к нижнему регистру
                        $vocalist->plaintext = mb_strtolower((mb_convert_encoding(($vocalist->plaintext), 'utf-8', mb_detect_encoding(($vocalist->plaintext)))), 'UTF-8');
                        //получаем id исполнителя из моей базы
                        $id_vocalist = $this->songs_model->check_vocalist(trim($this->db->escape($vocalist->plaintext)), trim($this->db->escape($this->translit($vocalist->plaintext))), $category);
                        //Нашли все песни исполнителя
                        $data_songs = file_get_html($vocalist->href);
                        //если есть хотя бы одна песня такого исполнителя - идём дальше
                        if (count($data_songs->find('#dle-content div.left-news-band a'))) {
                            foreach ($data_songs->find('#dle-content div.left-news-band a') as $songs) {
                                //Получим название песни. Удалим название исполнителя.
                                $name_song = substr(preg_replace('/\s\s+/', ' ', $songs->plaintext), strlen(trim($vocalist->plaintext)) + 1);
                                $name_song = trim($name_song);
                                //приводим название песни в нижний регистр
                                $name_song = mb_strtolower((mb_convert_encoding(($name_song), 'utf-8', mb_detect_encoding(($name_song)))), 'UTF-8');
                                //Транслитизируем название песни (моя самописная функция)
                                $name_song_translit = $this->translit($name_song);
                                //Отсекаем все пустые названия
                                if ($name_song == '' || $name_song_translit == '')
                                    continue;   
                                //Проходим по всем страницам навигации (пейджер, постраничная навигация)
                                $num_page = 0;
                                foreach ($songs->find('div.navigation a') as $num) {
                                    //если число - сравниваем, а не нашли ли мы ещё одну страницу навигации
                                    if (is_int($num->plaintext)) {
                                        if ($num->plaintext > $num_page)
                                            $num_page = $num->plaintext;
                                    }
                                }
                                echo $num_page . '<br />';
                                //загрузим текст песни
                                $text_songs = file_get_html($songs->href);
                                if (count($text_songs->find('div.full-news-full div[id] p'))) {
                                    foreach ($text_songs->find('div.full-news-full div[id] p') as $text_song) {
                                        //очищаем всякие ненужны ссылки и спаны
                                        foreach ($text_song->find('span') as $span) {
                                            $span->outertext = '';
                                        }
                                        foreach ($text_song->find('a') as $a) {
                                            $a->href = '';
                                            $a->outertext = '';
                                        }
                                        //выводим исполнителя, песню и текст
                                        echo $name_song .>]*>\s*)+/i", "<br />", $text_song->outertext, 1);
                                        //вставляю в мою базу текст песни и исполнителя (самописная функция)
                                        $result = $this->songs_model->check_song(trim($this->db->escape($name_song_translit)), trim($this->db->escape($name_song)), trim($this->db->escape($id_vocalist)), trim($this->db->escape_str(preg_replace("#(:?<br />){2,}#i", "<br />", strip_tags($text_song->outertext, '<br /><br><b><strong><p>')))));
                                        //если добавили - увеличим счётчик новых песен
                                        if ($result != -1) {
                                            $new_songs++;
                                        }
                                        $i++;
                                        //выйдем, тут всякие косяки бывают
                                        break;
                                    }
                                }
                                //теперь аналогично пробегаем по остальным страницам
                                if ($num_page > 0) {
                                    $text_songs = file_get_html($songs->href . 'page/' . $num_page);
                                    if (count($text_songs->find('div.full-news-full div[id] p'))) {
                                        foreach ($text_songs->find('div.full-news-full div[id] p') as $text_song) {
                                            foreach ($text_song->find('span') as $span) {
                                                $span->outertext = '';
                                            }
                                            foreach ($text_song->find('a') as $a) {
                                                $a->href = '';
                                                $a->outertext = '';
                                            }
                                            echo $name_song . '<br />';
                                            echo $songs->href . '<br />';
                                            echo $text_song->outertext .>]*>\s*)+/i", "<br />", $text_song->outertext, 1);
                                            $result = $this->songs_model->check_song(trim($this->db->escape($name_song_translit)), trim($this->db->escape($name_song)), trim($this->db->escape($id_vocalist)), trim($this->db->escape_str(preg_replace("#(:?<br />){2,}#i", "<br />", strip_tags($text_song->outertext, '<br /><br><b><strong><p>')))));
                                            if ($result != -1) {
                                                $new_songs++;
                                            }
                                            $i++;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return "<br />Парсер сайта rock-txt.ru завершён. Спарсено песен всего " . $i . ", из них новых " . $new_songs . " ";
    }

 Получилась вот такая здоровая функция, которая парсит тексты песен с сайта о роке. Написал её я за час. Спарсил 10 000 текстов песен. Думаю, что руками вы бы набивали такую базу очень и очень долго 🙂

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

Пока что на этом всё. В следующих уроках расскажу, как можно быстро и просто спарсить кучу информации на несколько десятков сайтов. Этот кейс должен обогатить каждого!

Всего доброго! Ретвиты, лайки и репосты приветствуются!

Если статья была для Вас полезной — Поделитесь ссылкой!

Советуем почитать

Закрепленные

Понравившиеся

Laravel 5.5 и парсинг. Что такое краулер (crawler). CleverMan.org

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

В этом году я успел побывать на двух очень крупных проектах. Оба
проекта касались финансовой тематики и их обслуживали команды приличных
размеров (около 40 программистов на проекте). В данном конкретном случае
я хочу акцентироваться на том, как создавались парсеры для порталов и
сервисов, и почему это было наказанием, разгребать эти легаси решения.

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

Итак,
с каким ужасом мне пришлось столкнуться. Первое — это то, что все
парсера писались разными программистами и в разные временные периоды.
Логика всех решений была абсолютно разная. Где-то парсили регулярками,
где-то simpleHtml либой, где-то через встроенные в PHP DOM инструменты. В
общем, кто в лес, кто по дрова.

Но все эти
решения объединяли некоторые факторы. А именно: отсутствие документации и
комментариев в коде, отсутствие самой концепции парсинга данных
(какого-то единого подхода и логики реализации), огромное количество
всяких проверок в DOM страницы (куча встроеных if-else, switch-case),
множественные циклы, встроенные друг в друга.

Ну
и самое страшное — это то, что сама логика жестко привязана к структуре
документа. В итоге, буквально через 3-6 мес. после написания этих
парсеров, сайты-доноры меняли дизайн, верстку, кто-то другой движок стал
использовать и т.д. И все решения по парсингу перестали работать, а
некоторые вообще не то забирали с других сайтов. Вначале разработчики
все эти парсера латали, подстраивая под изменения на сайте-доноре. Потом
в какой-то момент руководители плюнули на это и поручили менеджерам в
ручном режиме переносить информацию к нам на ресурс.

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

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

Дальше, следующая
проблема, которая вытекает из первой. Разработчик в трекере получает
задачу и тут же начинает ее пилить так, как он умеет или ему хочется. И
последняя проблема — это опять хотелки руководителя проекта сделать все
на вчера, а если что, то завтра уже сделаем как положено. В 99.99%
случаев, завтра не наступает никогда.

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

Давайте накидаем ряд пунктов (будем уже говорить о Laravel 5.5):

1. Должен быть единый парсер для всех наших задач.

2. Должна быть единая и понятная логика работы нашего парсера.

3. Добавление нового сайта донора в парсер должно занимать не более 5-10 минут

4. Парсер должен иметь свою админку с простым и понятным интерфейсом.

5. Парсер должен уметь забирать не только текст, но и файлы.

6. Если на сайте-доноре меняется структура документа, то перенастройка парсера должна занять пару минут.

7. Наш готовый парсер не должен требовать от программиста лазить в код.

8. Нам нужно вести лог того, что, когда и от куда мы забираем. Успешно ли мы завершили операцию.

9. Парсер должен понимать, что мы уже забирали эту информацию, а значит мы ее уже не забираем снова.

10. Мы можем парсить громадное количество источников, а значит нам нужна система импорта/экспорта настроек.

Я думаю, что для начала 10 пунктов будет достаточно. Хотя, на самом деле, их будет определенно больше.

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

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

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

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

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

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

Также
есть две кнопки вверху страницы: Все активировать и Все деактивировать.
Когда у вас один-два парсера, то они особо не нужны. А когда их у вас
десятки, как у меня, то без них вам придется вручную заходить в каждый
парсер и менять его статус. Это уйма времени и тонна раздражения.

Справа
(первый рисунок) вы видите уже сами настройки для парсера. При клике на
конкретный парсер вы увидите его настройки. Это уже отдельная таблица с
конкретными настройками (связана с таблицей парсера один к одному)
того, что именно и откуда нужно спарсить. Для разных задач/проектов
поля, которые вам нужно спарсить могут быть разными.

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

Вот так выглядит форма настроек:

Как
вы видите на изображении, каждое поле я получаю путем обращения к
конкретному DOM элемента. Это очень просто и быстро настраивается и
изменяется. Лазить каждый раз в код парсера мне не нужно.

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

Система импорта/экспорта сделана через JSON массив:

Нажали
кнопку экспорта, всплыло диалоговое окно с настройками. Скопировали их.
На другом проекте нажали кнопку импорта и вставили эти настройки в
такое же диалоговое окно. Все, настройки будут импортированы.

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

Теперь пару слов о самой логике
парсера.  Предположим, что вам нужно забрать десять новостей с какого-то
сайта. Как вы будете это делать? Самое простое и правильное — это
заходить парсером на некую общую страницу, где содержится список
новостей. Внимание! Не сама новость, а именно список новостей. Это может
быть главная страница ил конкретный раздел новостей.

В
настройках парсера у вас указана логика поиска таких ссылок на странице
донора. Итак, парсер заходит на страницу раздела и находит все ссылки,
которые введут на новости (конкретная новость с текстом, изображениями и
т.д.). Потом он начинает переходить по этим ссылкам и забирать контент,
согласно настройкам парсера.

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

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

Для
начала нам нужно создать отдельную и абстрактную бизнес логику самого
парсера. Я привык создавать в App папочку Modules и хранить там
отдельные классы для независимых решений.

В самом Ларавел последних версий встроен отличнейший инструмент для парсинга — это компонент от Symfony DomCrawler.

Его нужно импортировать в ваш класс парсера:

use Symfony\Component\DomCrawler\Crawler;

Метод получения контента примерно следующий:

/**
* Get content from html.
*
* @param $parser object parser settings
* @param $link string link to html page
*
* @return array with parsing data
* @throws \Exception
*/
public function getContent($parser, $link)
{
// Get html remote text.
$html = file_get_contents($link);

// Create new instance for parser.
$crawler = new Crawler(null, $link);
$crawler->addHtmlContent($html, 'UTF-8');

// Get title text.
$title = $crawler->filter($parser->settings->title)->text();

// If exist settings for teaser.
if (!empty(trim($parser->settings->teaser))) {
$teaser = $crawler->filter($parser->settings->teaser)->text();
}

// Get images from page.
$images = $crawler->filter($parser->settings->image)->each(function (Crawler $node, $i) {
return $node->image()->getUri();
});

// Get body text.
$bodies = $crawler->filter($parser->settings->body)->each(function (Crawler $node, $i) {
return $node->html();
});

$content = [
'link' => $link,
'title' => $title,
'images' => $images,
'teaser' => strip_tags($teaser),
'body' => $body
];

return $content;
}

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

Укажу о паре граблей, на которые я наступил. Инициализировать краулер можно и так:

    // Create new instance for parser.
$crawler = new Crawler($html);

Но
если делать так, то вы получите ошибки путей при парсинге изображений.
Поэтому, нужно обязательно передать в краулер линк (ссылка для
парсинга), а потом и страницу:

    // Create new instance for parser.
$crawler = new Crawler(null, $link);
$crawler->addHtmlContent($html, 'UTF-8');

При
создании роута обязательно делайте параметр secret token, чтобы только
вы могли запустить парсер с сайта (если вы не используете демон),
например так:

// Start parser. Secret token need for start parser via cron.
Route::get('start-parser/{token}', 'ParserController@start')->name('parser.start');

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

// Get parsered links;
$parseredLinks = ParserLog::whereParserId($parser->id)->select('parsered_indexes')->get();

$parserClass = new ParserClass();

// Make parsing sites from DB. Get parsing data.
$parserData = $parserClass->parserData($parser, $parseredLinks);

В
моем конкретном случае, получили для парсера все ссылки из лога,
которые уже были распарсены, и передали вместе с парсером в метод
parserData(). В переменную $parserData вы получите массив с «красивыми»
данными, которые можете сохранять в базу. А уже в самом парсере делаете
проверку на то, парсили ли вы по данной ссылке или нет.

Теперь
пару слов о том, что делать с изображениями в теле текста. Ведь все
изображения хранятся на сайте донора. Здесь мне тоже поможет краулер и
пакет UploadImage о котором я уже писал ранее (уже есть версия под Ларавел 5.5):

/**
* Save all remote images from body to disk and create new body.
*
* @param $body string body text
* @param $link string link to parsing site
*
* @return string new body
*/
public function saveImagesFromBody($body, $link)
{
// Create new instance for parser.
$crawler = new Crawler(null, $link);
$crawler->addHtmlContent($body, 'UTF-8');

// Get path for images store.
$savePathArray = \Config::get('upload-image')['image-settings'];
$savePath = UploadImage::load($savePathArray['editor_folder']);

$contentType = $savePathArray['editor_folder'];

// Get images from body.
$crawler->filter('img')->each(function (Crawler $node, $i) use ($contentType, $savePath) {
$file = $node->image()->getUri();

try {
// Upload and save image.
$image = UploadImage::upload($file, $contentType, true)->getImageName();

// Replace image in body.
$node->getNode(0)->removeAttribute('src');
$node->getNode(0)->setAttribute('src', $savePath . $image);
$node->getNode(0)->removeAttribute('imagescaler');
$node->getNode(0)->removeAttribute('id');
$node->getNode(0)->removeAttribute('class');
$node->getNode(0)->removeAttribute('srcset');
$node->getNode(0)->removeAttribute('sizes');

} catch (UploadImageException $e) {
return $e->getMessage() . '<br>';
}
});

$newBody = strip_tags($crawler->html(), '<img><span><iframe><blockquote><div><br><p>');

return $newBody;
}

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

В конце из текста вырезаем все html тэги, кроме разрешенных.

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

// Add post to facebook page.
if($parser->facebook) {
$this->facebookAddPostToPage(route('post.show', $post->slug), $post->title);
}

Указанный метод проверяет ваши ключи и делает публикацию на странице фэйсбука. Лично я использую для этого вот этот пакет: https://github.com/SammyK/LaravelFacebookSdk

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

Парсер
срабатывает по крону через каждые пол часа в дневное время. Все
работает четко, как часы. После сохрания постов на сайте они сразу же
постятся на страницу фэйсбука: https://www.facebook.com/YouSuper.org/

Как
видите, ничего сложного нет. Сам файл парсера занял 300 строк кода, а
контроллер — 200 строк. Да, еще момент. Для того, чтобы работать с
категориями, вам придется сделать массив со словарем, по которому вы
сможете получить идентификатор вашей категории (ключ массива), в
зависимости от полученного из парсера названия категории (значения
массива), например так:

/**
* @var array Rubrics dictionary.
*/
public $rubrics = [
1 => ['Авто', 'Авто/Мото', 'Авторевю'],
2 => ['Анекдоты', 'Смешное'],
3 => ['Баяны', 'Реклама']
];

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

Парсер курсов валют на PHP « Блог вебмастера Романа Чернышова

Хочу поделиться с вами некоторыми наработками в области парсинга(граббинга), в данном случае речь пойдет о парсинге курсов валют. В качестве донора мы будем рассматривать сайт ЦБРФ, т.к. он всегда поддерживает актуальные данные, всегда доступен и вообще многие сайты берут информацию о курсах именно с него.

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

Я предлагаю рассмотреть два рабочих варианта, два скрипта написанных на PHP, но работающих по разному с данными в разных форматах. Тем самым не только достичь поставленной цели, а также научится парсить HTML(разбором дерева DOM) таблицы и XML потоки.

Вариант первый, DOM, таблицы.

<?php
$date = date('d.m.Y');
$url="http://www.cbr.ru/currency_base/D_print.aspx?date_req=$date"; // URL страницы с курсами валют на сегодня
$html = file_get_contents($url); // Читаем содержимое HTML страницы
$charset = 'UTF-8'; // кодировка получаемой страницы
 
// на данном этапе, находим на в коде блок с классом header2, и все что до него удаляем, т.к. оно нам ненужно, там содержится ненужная нам информация
$pos=mb_strpos($html,'<table>', 0, $charset); // позиция
$html=mb_substr($html,$pos,mb_strlen($html, $charset), $charset); // обрезаем до указанной позиции, удаляя все лишнее
 
$dom = new domDocument; // создаем объект дерева DOM
$dom->loadHTML($html); // загружаем в него спарсенную страницу
 
$dom->preserveWhiteSpace = false;
//echo $html;
$tables = $dom->getElementsByTagName('table'); // получаем из дерева DOM первую таблицу, ею является как раз таблица содержащая курсы валют
$rows = $tables->item(0)->getElementsByTagName('tr'); // получаем из таблицы все строки
 
$i=0;
$curs = array(); // массив который будет хранить данные
foreach ($rows as $row) // беребор полученных строк
    {
	if($i==0) {$i++; continue;} // первую строку пропускаем, т.к. она содержит заголовки столбцов а не данные
        $cols = $row->getElementsByTagName('td'); // разбираем все строки по столбцам
 
 
	// записываем в полученные данные в массив, для удобного представления и работы дальше
        $curs[$i][0]=$cols->item(0)->nodeValue; // Цифр. код
        $curs[$i][1]=$cols->item(1)->nodeValue; // Букв. код 
        $curs[$i][2]=$cols->item(2)->nodeValue; // Единиц
        $curs[$i][3]=$cols->item(3)->nodeValue; // Валюта
        $curs[$i][4]=$cols->item(4)->nodeValue; // Курс
	$i++;
    }
print_r($curs);// выводим полученный массив

Вариант второй, XML.

<?php
$url = "http://www.cbr.ru/scripts/XML_daily.asp"; // URL, XML документ, всегда содержит актуальные данные
$curs = array(); // массив с данными
 
// функция полчуния даты из спарсенного XML
function get_timestamp($date)
 {
     list($d, $m, $y) = explode('.', $date);
     return mktime(0, 0, 0, $m, $d, $y);
 }
 
 
if(!$xml=simplexml_load_file($url)) die('Ошибка загрузки XML'); // загружаем полученный документ в дерево XML
$curs['date']=get_timestamp($xml->attributes()->Date); // получаем текущую дату
 
foreach($xml->Valute as $m){ // перебор всех значений
   // для примера будем получать значения курсов лишь для двух валют USD и EUR
   if($m->CharCode=="USD" || $m->CharCode=="EUR"){
    $curs[(string)$m->CharCode]=(float)str_replace(",", ".", (string)$m->Value); // запись значений в массив
   }
  }
 
print_r($curs);

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

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

Похожие записи

Парсинг сайтов с помощью python: плюсы и минусы, краткая инструкция для чайников

def readFile(fileName):

                with open(fileName) as inputFile:

                               text = inputFile.read()

                return text

def parse_bs(fileName):

                results = []

                text = readFile(fileName)

                variableBS = BeautifulSoup(text)

                filmList = filmList = variableBS.find("div", {"class": "profileFilmsList"})

                itemBS = filmList.find_all("div", {"class": ["item", "item even"]})

                for item in itemBS:

# получение идентификаторов фильмов

                               movieLink = item.find("div", {"class": "nameRus"}).find("a").get("href")

                               movieDesc = item.find("div", {"class": "nameRus"}).find("a").text

                               movieId = re.findall("\d+", movieLink)[0]

# получение английских названий

                               nameEng = item.find("div", {"class": "nameEng"}).text

#получение даты и времени

                               watchDatetime = item.find("div", {"class": "date"}).text

                               dateWatched, timeWatched = re.match("(\d{2}\.\d{2}\.\d{4}), (\d{2}:\d{2})", watchDatetime).groups()

# получение рейтинга от пользователя

                               userRating = item.find("div", {"class": "vote"}).text

                               if userRating:

                                               userRating = int(userRating)

                               results.append({

                                                               "movieId": movieId,

                                                               "nameEng": nameEng,

                                                               "dateWatched": dateWatched,

                                                               "timeWatched": timeWatched,

                                                               "userRating": userRating,

                                                               "movieDesc": movieDesc

                                               })

                return results

def parse_lxml(fileName):

                results = []

                text = readFile(fileName)

                wood = html.fromstring(text)

                filmListLxml = wood.xpath('//div[@class = "profileFilmsList"]')[0]

                itemsLxml = filmListLxml.xpath('//div[@class = "item even" or @class = "item"]') 

                for item_lxml in itemsLxml:

# получение идентификаторов фильмов

                               movieLink = item_lxml.xpath('.//div[@class = "nameRus"]/a/@href')[0]

                               movieDesc = item_lxml.xpath('.//div[@class = "nameRus"]/a/text()')[0]

                               movieId = re.findall("\d+", movieLink)[0]

# получение английских названий

                               nameEng = item_lxml.xpath('.//div[@class = "nameEng"]/text()')[0]

#получение даты и времени

                               watchDatetime = item_lxml.xpath('.//div[@class = "date"]/text()')[0]

                               dateWatched, timeWatched = re.match("(\d{2}\.\d{2}\.\d{4}), (\d{2}:\d{2})", watchDatetime).groups()

# получение рейтинга от пользователя

                               userRating = item_lxml.xpath('.//div[@class = "vote"]/text()')

                               if userRating:

                                               userRating = int(userRating [0])

                               results.append({

                                                               "movieId": movieId,

                                                               "nameEng": nameEng,

                                                               "dateWatched": dateWatched,

                                                               "timeWatched": timeWatched,

                                                               "userRating": userRating,

                                                               "movieDesc": movieDesc

                                               })

                return results

Как спарсить данные с другого сайта

В данном посте расскажем, как можно спарсить данные с «чужого» сайта и сохранить их у себя, с помощью php скрипта.

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

Что же такое «парсинг сайтов«, это получение информации из структурованного языка разметки HTML, в формате пригодного для дальнейшей работы (сохранения, обработки) и т.п. 

Парсинг информации состоит из нескольких этапов

1 этап. Определить доступность сайта для парсинга.

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

В этом вам поможет PHP библиотека сUrl. Сразу скажу, что даже самая простая система защиты от «парсинга», сильно затруднит работу скрипта. Во-первых, никто не знает, сколько у сайта-донора таких систем, во-вторых каждую такую систему, нужно обходить, и это увеличит скорость работы скрипта.

2 этап. Парсинг страниц.

Здесь все просто, в PHP имеется прекрасная библиотека для работы с HTML документами.  Simple Html Dom, скачать можно здесь.

Пример кода:

Можно еще воспользоваться встроенной библиотекой DomDocument. Но она больше предназначена для работы с XML документами. И если верстка имеет ошибки (например незакрытые тэги), то данная библиотека сгенерериует ошибку.

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

Пример кода:

3 этап. Сохранение результатов парсинга.

Для сохранения результатов парсинга, проще всего воспользоваться реляционными базами данных. Такие как mysql или postgresql

 

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

 


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

Парсинг — Парсинг и все, что связано с ним

Сегодня я Вам расскажу о стандарте WebDriver от W3C. Данный стандарт применим для управления браузерами посредством замечательного инструмента — selenium. Основным ключевым моментом является отправка команд и получение ответа от selenium посредством REST технологии (где запрос на получение данных осуществляется путем отправки GET запроса, а установка значения или изменения состояния посредством POST запроса, DELETE очистка куков, закрытие окон, закрытие сессии).

Читать далее «WebDriver»

    Сегодня пойдет речь об еще одном интересном инструменте — PhantomJS. Что это такое и с чем его едят?
    PhantomJS — это браузер в консоле на основе Webkit, позволяющий посредством JavaScript производить управление им для серфинга  и автоматизация действий в сети Интернета. Распространяется данная программа под лицензией — BSD License. Официальный сайт — http://phantomjs.org/. К сожалению скудная документация и к тому же только на англ. языке находится у них на сайте — http://phantomjs.org/documentation/. Читать далее «PhantomJS — Webkit в консоли.»

  Вчера, 26 мая 2016г. обновился PHP  7 до версии 7.0.7.  Были исправлены несколько ошибок:

  • исправлена утечка памяти при вызове $this в анонимной функции (#71737)
  • исправлена ошибка перезаписи имен классов (#72159)
  • исправлена ошибка при работе implode с большими числами в массиве (#72100)
  • исправлена ошибка при вызове константы — CURLE_SSL_CACERT_BADFILE (#68658)

С полным списком исправлений можно ознакомиться здесь.

    Очень часто встает вопрос отправки POST запроса на удаленный сервер. Давайте подробно рассмотрим как это сделать с помощью библиотеки CURL. Читать далее «CURL: POST запрос, составное содержимое (multipart/form-data)»

    В этой статье рассмотрим еще одну успешную представительницу программ по парсингу — XRumer. Основное назначение этой программы не собирать данные, а публиковать данные на сайтах, форумах и в социальных сетях. Читать далее «XRumer»

    Рассмотрим еще одну программу, которая отлично справляется с автоматизацией процесса парсинга — Datacol. Читать далее «Datacol»

   Встречайте обновление PHP до версии 7.0.6! PHP не стоит на месте и развивается! И очередное обновление тому подтверждение. Это новость порадовала поклонников PHP.  В этом обновлении было куча исправлений «багов», что тоже не может не радовать! Итак, что же было исправлено? Читать далее «Новости. Вышло обновление PHP 7»

    В PHP есть замечательный класс — DOMDocument. В чем же его замечательность? Данный класс изначально предназначался для парсинга XML файлов. Он представляет из себя удобный интерфейс по манипуляции элементами DOM модели. Данный класс можно использовать не только для парсинга XML документов, но и для HTML. Читать далее «DOMDocument»

    Guzzle — удобная библиотека для получения содержимого веб сайта и последующей обработки его. Данная библиотека по умолчанию использует — CURL, а в случае ее отсутствия, то использует обертку — PHP потоков (php stream). Guzzle распространяется под лицензией — MIT. Она способна выполнять как синхронные запросы к веб ресурсу, так и работать с асинхронными запросами. Читать далее «Guzzle»

Понимание того, как анализируется PHP

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

  1. Веб-браузер запрашивает документ с расширением .php (или любым расширением, установленным для обработки как файла PHP).

  2. Веб-сервер отправляет запрос на синтаксический анализатор PHP, который либо встроен в двоичный файл веб-сервера, либо существует отдельно как фильтр или исполняемый файл CGI.

  3. Анализатор PHP сканирует запрошенный файл на предмет наличия кода PHP.

  4. Когда синтаксический анализатор PHP находит код PHP, он выполняет этот код и помещает полученный результат (если есть) в то место в файле, которое раньше занимало код.

  5. Этот новый выходной файл отправляется обратно на веб-сервер.

  6. Веб-сервер отправляет выходной файл веб-браузеру.

  7. Веб-браузер отображает результат.

Поскольку код PHP анализируется сервером, этот метод выполнения кода называется на стороне сервера. Когда код выполняется браузером, например, с помощью JavaScript, он называется клиентской стороной.

Совместное проживание кода и теги PHP

Чтобы объединить код PHP с HTML, код PHP должен быть экранирован , или выделен отдельно от HTML. Следующий метод является конфигурацией по умолчанию движка PHP:

  

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

Теперь пора написать этот первый сценарий. Ваш первый сценарий PHP отобразит «Hello World! Я использую PHP!» в окне браузера.

Сначала откройте ваш любимый текстовый редактор и создайте простой текстовый файл с именем first.php. В этом текстовом файле введите следующий код:

     Мой первый скрипт PHP     Привет, мир! Я использую PHP! 

\ n"; ?>

Сохраните этот файл и поместите его в корневой каталог документов вашего веб-сервера. Теперь откройте его в браузере по его URL-адресу http: // 127.0.0.1 / first.php. В окне браузера вы должны увидеть это:

 Hello World! Я использую PHP! 
Примечание

Если у вашего сервера есть реальный компьютер и доменное имя, такое как www.yourcompany.com, не стесняйтесь использовать его вместо 127.0.0.1 (который является локальным хостом по умолчанию).

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

     Мой первый скрипт PHP    

Привет, мир! Я использую PHP!

Поскольку PHP-код был обработан синтаксическим анализатором PHP, все, что остается видимым, это вывод HTML.

Теперь взгляните на PHP-код, используемый в скрипте. Он содержит три элемента: команду (эхо), строка (

Hello World …) и признак конца инструкции (;).

Теперь ознакомьтесь с echo, потому что это, вероятно, ваша наиболее часто используемая команда. Функция echo () используется для вывода информации — в данном случае для вывода

Hello World! Я использую PHP!

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

Важность терминатора инструкции

Знак конца инструкции, также известный как точка с запятой, является обязательным. Если вы не завершите свою команду точкой с запятой, механизм PHP не будет правильно анализировать ваш код PHP, и возникнут уродливые ошибки.Например, этот код:

  Привет, мир! Я использую PHP! 

\ n" echo "

Это еще одно сообщение.

"; ?>

выдает эту неприятную ошибку:

 Ошибка синтаксического анализа: ошибка синтаксического анализа, ожидание "," или ";" в /path/to/your/file/filename.php в строке 9 

Избегайте этой ошибки любой ценой — не забудьте завершить команды точкой с запятой!

Экранирование вашего кода

Прямо здесь, не забывая заканчивать ваши команды точкой с запятой, не забывает об экранировании таких элементов, как кавычки.Когда вы используете кавычки внутри других кавычек, внутренние пары должны быть отделены от внешней пары с помощью символа escape (\) (также известного как обратная косая черта). Например, следующий код вызовет еще одну ошибку синтаксического анализа, потому что термин «круто» заключен в двойные кавычки в строке с двойными кавычками:

  Я думаю, что это действительно" круто "! 

"; ?>

Вместо этого этот код должен выглядеть так:

  Я думаю, что это действительно \" круто \ "! 

"; ?>

Теперь, когда внутренние кавычки экранированы, синтаксический анализатор PHP пропустит их, потому что знает, что эти символы должны быть просто напечатаны и что они не имеют другого значения.Та же концепция верна для элементов в одинарных кавычках внутри других строк в одинарных кавычках — экранируйте внутренний элемент. Строки в одинарных кавычках внутри строк в двойных кавычках и наоборот не требуют экранирования символов.

Комментирование кода

Добавляете ли вы комментарии к статическим HTML-документам или к сценариям PHP, комментирование кода — хорошая привычка для развития. Комментарии помогут вам и другим людям, которым, возможно, придется редактировать ваши документы позже, понять, что происходит в ваших документах.

Комментарии HTML игнорируются браузером и содержатся в тегах . Например, следующий комментарий напоминает вам, что следующий за ним код содержит изображение вашего логотипа:

  

Аналогичным образом, PHP-комментарии игнорируются механизмом синтаксического анализа. PHP-комментариям обычно предшествуют двойные косые черты, например:

 // это комментарий в PHP-коде 

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

 # Это стиль в стиле оболочки comment 

и

 / * Здесь начинается комментарий в стиле C, который занимает две строки * / 

Комментарии HTML и PHP широко используются в этой книге для объяснения блоков кода.Привыкайте читать комментарии и постарайтесь выработать привычку их использовать. Написание чистого, безошибочного кода, с большим количеством комментариев и пробелов сделает вас популярным среди ваших коллег-разработчиков, потому что им не придется особо много работать, чтобы выяснить, что пытается сделать ваш код!

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

Как анализировать файлы HTML как PHP — блог веб-разработки

Есть много причин анализировать файлы HTML как PHP .Некоторые веб-мастера делают это, потому что они превращают старый статический веб-сайт в динамический и не хотят терять рейтинг страницы. Другие веб-сайты делают это, потому что поисковые системы, похоже, отдают предпочтение веб-страницам с окончанием .html по сравнению со страницами с динамическим окончанием .php. Или, возможно, вы делаете это из соображений безопасности … Вы не хотите, чтобы посетители знали, какой язык сценариев вы используете для запуска вашего веб-сайта.

К счастью, синтаксический анализ файлов HTML как PHP легко выполняется на Linux Apache с помощью файла htaccess .

Создание файла HTACCESS

Если вы никогда раньше не видели и не слышали о файле HTACCESS , не беспокойтесь. Файлы Htaccess — это простые текстовые файлы, которые сохраняются с расширением .htaccess. И они легко создаются с помощью простого текстового редактора, такого как Блокнот или WordPad.

Код

Хотите верьте, хотите нет, но вам нужна всего одна строка кода, чтобы совершить действие. К сожалению, код варьируется в зависимости от конфигурации вашего сервера. И если ваш веб-хостинг не предоставляет документацию, невозможно узнать, какой код будет работать.Но вот типичные примеры кода ниже. (Примечание: если эти образцы кода не работают, возможно, потребуется проконсультироваться с вашим хостом.)

⇒ На веб-хостах, на которых работают две версии PHP:

Некоторые веб-хосты, которые работают или уже работают, две версии PHP, например PHP4 и PHP5, обычно имеют обработчик PHP5. В приведенном ниже примере кода все файлы .html и .htm будут анализироваться как PHP. (Этот код был протестирован на хостингах HostGator и InMotion .)

AddHandler application / x-httpd-php5.html .htm

На большинстве других веб-хостов:

Для хостов, на которых работает только одна версия PHP, должен работать следующий код. (Этот код был протестирован на веб-хостингах Superb и LunaPage .)

AddType application / x-httpd-php .html .htm

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

AddHandler application / x-httpd-php.html .htm

или

AddHandler x-httpd-php .html .htm

Некоторым веб-хостам, таким как GoDaddy , требуются обе директивы. Таким образом, ваш код будет выглядеть так:

AddType application / x-httpd-php .htm .html
AddHandler x-httpd-php .htm .html

В крайнем случае, вы также можете попробовать это multi -строчный подход, который использует директиву SetHandler :


приложение SetHandler / x-httpd-php

или


приложение SetHandler / x-httpd-php5

Сложности

Иногда ни один из приведенных выше примеров кода не работает. В этом случае вы можете сделать несколько вещей:

  1. Проконсультируйтесь с вашим веб-хостом чтобы узнать о конфигурации вашего сервера и определить, следует ли использовать какой-либо другой код.
  2. Проверьте правильность расширения . Если вы плохо знакомы с файлами htaccess, при их создании легко ошибиться. Самая распространенная ошибка — сохранить файл с неправильным расширением. Чтобы исправить это, вы можете легко изменить имя файла после загрузки на свой сервер. Просто переименуйте файл так, чтобы у него не было имени, а было только расширение. Таким образом, имя файла должно выглядеть как « .htaccess ».
  3. Подождите . Иногда на хостах есть что-то, что называется кешем на стороне сервера.Это означает, что файлы «вступят в силу» через некоторое время. Например, если вы используете GoDaddy, вам следует подождать около 30 минут.
  4. Проверить разрешения . Убедитесь, что ваши файлы htaccess имеют нужные разрешения. Для просмотра или изменения разрешений вам потребуется утилита CHMOD .

Проблемы безопасности и производительности

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

В результате мы рекомендуем это как отличное решение для небольших веб-сайтов. (Маленькие веб-сайты — это веб-сайты с менее чем 50 страницами.) Однако по мере увеличения размера вашего веб-сайта было бы неплохо выбрать более надежное решение, которое сможет обслуживать веб-сайт любого размера.

Теги: Apache, кеш, файл htaccess, Linux, PHP

10 невероятно полезных PHP-инструментов, о которых вы должны знать

PHP — один из самых универсальных языков для веб-дизайна и разработки.Вот почему 80% Интернета написано на PHP. Вы можете закодировать простую веб-страницу на PHP или использовать инструменты PHP для создания сложных серверных скриптов.

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

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

1. PHPCPD

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

Связь с сервером

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

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

Настроить эти сервисы легко, и они проработают весь проект WordPress всего за несколько минут.

2. PHP Markdown

Пакет библиотеки, который может преобразовать ваш текст в HTML, может стать вам помощником, когда вы пытаетесь разобрать большой проект.Как только вы включите инструмент для чтения и записи в текстовом формате, он будет преобразован в XHTML или HTML.

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

PHP Markdown — идеальный инструмент для смешанной команды программистов и постоянных участников.

3. Синтаксический анализатор PHP

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

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

4. PHPCheckstyle

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

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

Упаковывая все в простой для понимания формат, он служит полезным инструментом для любого уровня подготовки.

5. Анализатор PHP

Анализатор

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

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

6. PHP-Текстиль

PHP Textile отлично подходит для тех, кто имеет опыт работы с языком разметки Textile. Этот парсер работает в PHP как генератор веб-текста, конвертируя сложный язык разметки в HTML.

Это еще один полезный инструмент, если большая часть вашей работы и взаимодействия сосредоточена на интерфейсе пользователя. Если вам нужен синтаксический анализатор, соответствующий вашему опыту работы с Textile, не ищите дальше.

7. Анализ

Если вам нужен быстрый и расширяемый анализатор уценки для PHP, Parsedown может быть для вас инструментом. Текст Markdown быстро преобразуется в пригодный для использования PHP и HTML менее чем за секунду.

Если вы только начинаете или видите ошибки в тексте, перетащите его в синтаксический анализатор и сравните то, что у вас есть на вашей странице, с тем, что появляется в Parsedown.Это надежный инструмент для тестирования и поиска ошибок.

8. Песочница PHP

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

Этот синтаксический анализатор предотвращает небезопасный код и помогает преобразовывать вызываемые объекты в строки. Если вам нужно быстро запустить какой-то код, песочница PHP преобразует код и проверит на наличие ошибок.

9. Sabberworm

Sabberworm — отличный инструмент для файлов CSS, используемых для стилизации ваших страниц.Если они написаны на PHP, Sabberworm может их проанализировать. Этот инструмент позволяет разработчикам извлекать файлы CSS и предоставлять файлы в формате CSS.

Если вы только начинаете разбираться в стилях в PHP, Sabberworm поможет вам понять, как безопасно и эффективно вводить и выводить ваши стили в PHP.

10. PHPMD

Это PHP-версия Java-инструмента PMD. Для пользователей Java это может упростить переход к использованию PHP.

Есть несколько инструментов PHP, которые так же удобны для опытных пользователей Java, как PHPMD.Это новый инструмент без надежного набора предопределенных правил, но в ближайшем будущем он обязательно превратится во что-то великое.

Существуют инструменты PHP для любого уровня навыков

Независимо от вашего опыта программирования, вы найдете инструмент PHP, который поможет вам создать свой проект. Связь на стороне сервера с PHP без оптимизированного кода — головная боль. Эти инструменты будут уверены, что ваш код будет работать в обе стороны, возвращая нужные данные как можно быстрее.

Если у вас возникнут какие-либо вопросы о поиске подходящих инструментов PHP, свяжитесь с нами, чтобы как можно скорее запустить ваш PHP-проект.

Лучшие 7 инструментов для анализа и анализа вашего PHP-кода

Довольно странно видеть, как за эти годы изменилась вся экосистема PHP, сотруднику больше не нужно убеждать работодателя в том, что он хороший разработчик; ситуация изменилась, и найти хороших разработчиков PHP с каждым днем ​​становится все труднее.

PHP по-прежнему широко рекламируется как ведущий язык программирования начального уровня, который может освоить любой новый программист и начать обучение, но в последнее время Python и JavaScript становятся двумя языками, которые не только хороши для начала обучения, но и для поиска хорошо оплачиваемой работы!

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

1. Синтаксический анализатор PHP

PHP Parser — это проект по синтаксическому анализу кода, построенный на основе PHP; предназначен для версий PHP от 5.2 до 5.6. Этот конкретный синтаксический анализатор отлично подходит для статического анализа и позволяет программно управлять кодом любых приложений, которые работают с кодом. Парсер работает через абстрактное синтаксическое дерево (AST).

2. PHPSandbox

Полномасштабный класс песочницы PHP 5.3.2+, который использует PHP-Parser для предотвращения запуска небезопасного кода в изолированном коде.Итак, этот и тот, что выше, идут рука об руку. Некоторые из выделяющихся функций включают возможность переопределения вашего внутреннего PHP-кода, чтобы сделать его более безопасным и удобным для использования в песочнице. Вот страница, на которой документируется весь процесс.

3. Детектор сообщений PHP

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

  • Возможные ошибки
  • Код субоптимального
  • Слишком сложные выражения
  • Неиспользуемые параметры, методы, свойства

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

4. PHPCPD

PHPCPD — это детектор копирования / вставки (CPD) для кода PHP. Если вам нужно начать работу над большим проектом, который либо был заброшен ранее, либо следует старому способу программирования, то это единственный инструмент, который поможет вам проанализировать код, чтобы избежать повторяющихся функций и вызовов по всей базе кода. Его легко настроить, и он может проанализировать проект размером с WordPress менее чем за минуту.

5. PHPCheckstyle

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

6. Убенч

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

7.Анализатор PHP

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

Анализ и разбор вашего PHP-кода

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

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

Как разобрать HTML-файлы как PHP?

Обновлено 1 год назад

к
Хоселин Родригес

Вы можете использовать следующую директиву в.htaccess для синтаксического анализа файлов HTML как PHP. Точная строка, которую вам нужно добавить, будет отличаться для разных серверов , в зависимости от того, как именно Apache и PHP установлены и настроены. Но одна из этих строк (или наборов строк) должна помочь:

 AddHandler x-httpd-php .html .htm 
 AddHandler php-script .php .html .htm 
# Если сервер использует PHP 5, используйте :
# AddHandler php5-скрипт .php .html .htm

На серверах cPanel:

  
AddType application / x-httpd-ea-php72 .php .htm .html
AddHandler application / x-httpd-ea-php72 .php .htm .html

** В зависимости от версии PHP, которую вы используете, вам нужно будет заменить php72 на версию, которую вы используете. Например, если вы используете PHP 7.0, используйте application / x-httpd-ea-php70.

На серверах CloudLinux (все наши общие серверы Linux используют CloudLinux):

  
AddType application / x-httpd-alt-php72 .php .htm .html
AddHandler application / x-httpd-ea-php72 .php .htm .html

** В зависимости от версии PHP, которую вы используете, вам нужно будет заменить php72 на версию, которую вы используете. Например, если вы используете PHP 7.0, используйте application / x-httpd-alt-php70.

Чтобы убедиться, что он работает, создайте файл с именем phptest.html и поместите в него код PHP.Вот код, который вы можете использовать для тестирования:

  echo "PHP работает."; 
?>

Загрузите phptest.html на сервер и получите доступ к нему через браузер. Если на странице отображается «PHP работает», значит, все готово; но если он отображает код PHP или вообще ничего не работает, значит, это не сработало, и вам нужно будет попробовать разные строки в вашем файле .htaccess.

Возникли проблемы? Свяжитесь с нами, и наша команда будет рада помочь.

php fpm — NGINX не разбирает.php5 как .php

Я установил nginx с ISPconfig. Все работает нормально, кроме некоторых веб-сайтов, которые я перенес с сервера apache, к сожалению, имеет расширение .php5 , и я не знаю, как заставить nginx их анализировать. Я перепробовал множество решений и вариантов, но до сих пор не могу заставить их работать.

Я вставлю свои настройки из файлов, и если бы у кого-то был подобный опыт, которым хотелось бы поделиться, я был бы благодарен.

Часть настроек из файлов:
/ и т.д. / php5 / fpm / php.(. + \. php) (/.+) $;
# # ПРИМЕЧАНИЕ. У вас должно быть «cgi.fix_pathinfo = 0;» в php.ini
#
# # Только с php5-cgi:
# fastcgi_pass 127.0.0.1:9000;
# # С php5-fpm:
# fastcgi_pass unix: /var/run/php5-fpm.sock;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name;
# включаем fastcgi_params;
try_files $ uri = 404;
fastcgi_pass unix: / var / run / php5-fpm.носок;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name;
включить fastcgi_params;
}

Файл конфигурации Vhost для определенного домена с ошибкой:

 расположение ~ \ .php $ {
            try_files /58c4be432bbd2af65343c142b9ec45ec.htm @php;
        }


        location @php {
            try_files $ uri = 404;
            включить / etc / nginx / fastcgi_params;
            Кирилл 127.0.0.1: 9048;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name;
            fastcgi_intercept_errors on;
        }

        место расположения / {
                try_files $ uri $ uri / /index.php?q=$uri&$args;
        } 

/etc/php5/fpm/pool.d/www.conf не прокомментировал:

 security.limit_extensions = .php .php3 .php4 .php5 

.

И когда кто-то обращается к странице .php5 (на сайте более 500 обратных ссылок), браузер начинает загружаться, например, php-fpm, не разбирает .php5 файл:

 XX.XXX.X.XXX - - [26 / Фев / ​​2014: 22: 53: 07 +0000] "GET /sitemap.php5 HTTP / 1.1" 304 0 "-" "Mozilla / 5.0 (Windows NT 6.3; WOW64 ) AppleWebKit / 537.36 (KHTML, например Gecko) Chrome / 33.0.1750.117 Safari / 537.36 "
XX.XXX.XX.XXX - - [26 / Фев / ​​2014: 22: 54: 27 +0000] "GET /index.php5 HTTP / 1.1" 200 71941 "-" "Mozilla / 5.0 (Windows NT 6.3; WOW64; rv: 27.0) Gecko / 20100101 Firefox / 27.0 "
XX.XXX.X.XXX - - [26 / Фев / ​​2014: 22: 56: 43 +0000] "GET /sitemap.php5 HTTP / 1.1" 200 71941 "-" "Mozilla / 5.0 (Windows NT 6.3; WOW64; rv: 27.0) Gecko / 20100101 Firefox / 27.0 "

Как настроить nginx для анализа страниц .php5 , например .php ?

Заранее благодарю.

Библиотека синтаксического анализа PDF с открытым исходным кодом для PHP — анализ и извлечение данных PDF

Начало работы с PDFParser

Библиотека PDFParser будет автоматически загружена через командную строку композитора. Добавьте PDFParser в свой файл composer.json.

Добавить команду в composer.json

  {
   "требовать": {
    "смалот / pdfparser": "*"
    }
 }
  

Используйте композитор для загрузки пакета, выполнив команду:

Установите PDFParser через композитор

  $ ​​обновление композитора smalot / pdfparser 

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

Установите PDFParser вручную через композитор

  $ ​​обновление композитора  

Он загрузит все зависимости ( библиотека Atoum ) и сгенерирует файл autoload.php.

Анализировать файл PDF и извлекать текст с каждой страницы с помощью PHP API

PDFParser предоставляет функциональные возможности, которые позволяют компьютерным программистам анализировать документы PDF внутри своего собственного PHP-приложения.Во-первых, вам нужно создать необходимые объекты, затем загрузить файл PDF, проанализированный файл можно сохранить в переменной, а затем этот объект позволит вам обрабатывать страницу PDF за страницей. Теперь вы можете легко извлекать текст из всего PDF-файла или отдельно по страницам. После того, как документ проанализирован, вы можете легко извлечь текст с каждой страницы PDF-файла.

Извлечь метаданные из PDF-документа

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

Извлечь текст из определенного PDF-файла Страница

PDFParser позволяет разработчикам легко извлекать текст с определенных страниц, используя небольшой объем кода. API дает разработчикам возможность обрабатывать каждую страницу PDF-документа отдельно.