Giter Club home page Giter Club logo

nokogiri's Introduction

PHP Composer

Attention: New version can break compatibility, in that case use previous version under the v1.0 branch or tag which supports even php 5.4+

\nokogiri class is left for compatibility

In English На русском

HTML parser

This library is a fast HTML parser, which can work with invalid code (errors are ignored).
Under the hood is used LibXML.
As the input you can use HTML string in UTF-8 encoding or DOMDocument.
For the querying elements CSS selectors are used, which are transformed to XPath expressions internally.

Usage

Loading HTML

HTML errors are ignored

  • From HTML string $saw = new \nokogiri($html); $saw = \nokogiri::fromHtml($html);
  • From DOM elements $saw = new \nokogiri($dom); $saw = \nokogiri::fromDom($dom);

get($cssSelector)

$cssSelector elements have the following format: tagName[attribute=value]#elementId.className:pseudoSelector(expression)

$saw->get('div > a[rel=bookmark]')->toArray();

toArray()

Returns underlying DOM structure as an array.
Values are attributes, text content under #text key and child elements under numeric keys

toXml()

Returns HTML string

getDom() toDom()

Returns DOMDocument. Given true as the first argument - can also return DOMNodeList or DOMElement

Iteration over found elements

foreach ($saw->get('#sidebar a.topic') as $link){
    var_dump($link['#text']);
}

Implemented selectors

  • tag
  • .class
  • #id
  • [attr]
  • [attr=value]
  • :root
  • :empty
  • :first-child
  • :last-child
  • :first-of-type
  • :last-of-type
  • :only-of-type
  • :nth-child(a)
  • :nth-child(an+b)
  • :nth-child(even/odd)

Requirements

  • DOM
  • libxml >=2.9.0
  • PHP >= 7.3

License

MIT

What's new

2.0.0

  • Minimal PHP version 7.3
  • Minimal LibXML version 2.9.0
  • Complete refactoring
  • Partially changed behaviour, can break compatibility
  • HTML loading behaviour changed
  • Test coverage
  • Fixed work of nth-child and other selectors
  • Incorrect selectors now throw exceptions
  • New selectors added

1.0.0

  • First version, 2011
  • Minimal PHP version 5.4

nokogiri's People

Contributors

billionaire avatar niremizov avatar olamedia avatar positronium avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nokogiri's Issues

Парсинг по тегу

Привет, стоит задача доставать линки из sitemap.xml

$links = $this->nokogiri($this->filterHtml($html))->get('loc')->toArray();

в данном случае достает как содержимое тэга '< loc>', так и содержимое тега
'< image:loc>'

$singleLevel = tru

Строка 251
// $singleLevel = tru

P.S. сорри, неохото форк делать и пулл запрос... =/

Символы в выражении = Malformed xpath

Здравствуйте.
Если в выражении есть знаки %, #, ... то вылезает ошибка "Malformed xpath".
Например:
$saw->get("table[width=100%] td[bgcolor=#ffffff] p.table_text")->toArray();

Проверка атрибутов на наличие tr[class] ->> \\tag[@attr]

В некоторых случаях бывает полезно выбирать элементы только в том случае, если у них присутствует какой-либо атрибут. Пример таблицы:

<table>
    <tr></tr>
    <tr class='item'></tr>
    <tr class='item'></tr>
    ....
</table>

В такой разметке, первая строка таблицы это заголовок, а далее идут уже элементы списка... Пример: http://www.dns-shop.ru/search/?length_1=0&q=delonghi

В данный момент в случае использовании $nokogiti->get('table.catalog_view_list tbody tr[data-price_item_id]') - атрибут вообще не попадает в XPath запрос.

Text blocks

Currently, toArray() can return only single text block under "#text" key.

Sometimes this is not enough:

    <div>text<small>text2</small>text3</div>

(And you should use getDom() in this case atm)

I want to listen some opinions about how to make text blocks available via toArray() method, preferably not breaking compatibility.

аналог innerHTML

Здравствуйте.
Подскажите пожалуйста, как получить содержимое элемента?
Допустим я беру содержимое тега , как после метода ->toXml() получить содержимое без него?
Только своей регуляркой?

p.s. в коде в регулярках вы используете [0-9] , а чем хуже \d ?
или же [a-z0-9]/i , когда можно использовать \w , хотя конечно тут есть минус, потому что пропустит и знак подчёркивания "_"

Emty cells in table

Hello, thank you for your work.

Let's assume the following html.

2443 3435345

$doc = new \nokogiri($htmlContent);
$doc->get('td')->toTextArray();

As a result I got an error with two items only, empty td is not included into result array.
I tried $doc->get('td, td:empty') but it didn't help.

Is it possible to make some changes to got an array with this item and
[#text] value equal null or emty?

Получить следующий невложенный элемент.

Доброго дня! Спасибо большое за инструмент, очень удобно! Столкнулся с проблемой и никак не могу решить, подскажите пожалуйста.

У меня есть DIV , в нем лежат вперемешку не вложенные никуда элементы IMG / p / h3, от 10 до 50 каждого может быть .

Как получить следующий за IMG элемент H3 или наоборот?

$items_all = $saw->get('div.post_content')->toArray();
items_all = {array} [1]
 0 = {array} [6]
  class = "post_content"
  itemprop = "articleBody"
  #text = {array} [28]
  p = {array} [12]
  div = {array} [6]
  h3 = {array} [10]

Не работают псевдоклассы

Видимо проекту конец, однако это пока это самый лучший парсер, среди попробованных...

На странице есть 10 штук <table class="weather-table"> ... </table>. Нужно выбрать первую таблицу.
Пишу $saw_page->get(".weather-table:first-child")->toArray(); и получаю все 10 таблиц.
Помогите пожалуйста исправить.

Поиск элементов по Xpath

Приветствую. Уже довольно давно и успешно использую Вашу библиотеку, и с поиском элементов по CSS проблем нету вообще. Но, иногда, нужно(и быстрее будет) искать элементы по Xpath выражению.
Возможно я не внимательно изучил, код, и все же, как искать элементы на странице по Xpath а не по CSS?

Корректная загрузка UTF-8 при отсутствии признаков в документе

Сделать ли отдельный метод?

Варианты

Вставка XML тега, удаление после загрузки

$doc = new DOMDocument();
$doc->loadHTML('<?xml encoding="UTF-8">' . $html);
// dirty fix
foreach ($doc->childNodes as $item)
    if ($item->nodeType == XML_PI_NODE)
        $doc->removeChild($item); // remove hack
$doc->encoding = 'UTF-8'; // insert proper

Вставка meta после head

$html=preg_replace('/<head[^>]*>/','<head><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">',$html); 

Парсер выдает нотис

Notice: Undefined index: rel in .../nokogiri.php5 on line 163
При парсинге страницы получаю нотис. Сам не лез в библиотеку, не разбирался. Хотелось бы чтобы автор сам посмотрел и проверил, мне интересно, это только у меня такая проблема. И еще есть проблема, на выходе получаю массив в ISO-8859-5, при том что на в ходе в UTF-8.

Подправил 163 строку
$query .= $this->getXpathSubquery($left, isset($subs['rel']) ? '>'===$subs['rel'] : false, $compile);

Call to undefined method DOMNodeList::hasChildNodes()

Думаю что это ошибка, но не разбирался особо.
Дергаю $nokogiri->get('#login')->toText();
Получаю ошибку - Call to undefined method DOMNodeList::hasChildNodes()
Поизучал код, думаю проблема решается если добавить || $node instanceof DOMNodeList в строку 261, в условие метода protected function _toTextArray()

protected function _toTextArray($node = null, $skipChildren = false, $singleLevel = true){
        $array = array();
        if ($node === null || $node instanceof DOMNodeList ){
            if ($this->_dom instanceof DOMNodeList){
                foreach ($this->_dom as $node){
                    if ($singleLevel){
                        $array = array_merge($array, $this->_toTextArray($node, $skipChildren, $singleLevel));
                    }else{
                        $array[] = $this->_toTextArray($node, $skipChildren, $singleLevel);
                    }
                }
                return $array;
            }
            $node = $this->getDom();
        }
...

Установка кодировки

Подскажите как можно установить кодировку документа самостоятельно
если в html не указана кодировка, то nokogiri неверно отображает слова
к примеру при парсинге страницы https://games.mail.ru/pc/news/ срабатывает метод loadHtml хотя должен сработать loadHtmlNoCharset так как там в коде нет установленной кодировки

из-за этого весь текст отображается в неверной кодировке

если извернуться и сделать что-то типа такого

$html = file_get_contents('https://games.mail.ru/pc/news/');
$html .= '<meta http-equiv=Content-Type content="text/html;charset=UTF-8">';

то страница парсится в верной кодировке

PS. в принципе разобрался, можно сделать вот так

$html = file_get_contents('https://games.mail.ru/pc/news/');
$saw = nokogiri::fromHtmlNoCharset($html);

но не знаю насколько это правильн

fromDom() и toText и версия libxml

Полагаю в README есть смысл добавить в Requirements информацию о минимальной версии libxml. Обнаружил при использовании Libxml версии 2.7.8 - появляется следующее поведение:

Функция:
`
public function getDomElementsText($dom_element) {

$parser = nokogiri::fromDom($dom_element);

return $parser->toText();

}
`

На выходе вернет HTML/текст в неверной кодировке, думал проблема в версии PHP, но обновление до 5.5 не помогло. Сменил libxml на 2.9.2 и HTML на выходе нормальный в UTF8.

:nth-child(3)

Не работают селекторы с псевдоклассами типа :nth-child(3).
Исправил по-быстрому, вставив
}elseif(preg_match("/^[0-9]+$/", $e)){
$brackets[] = 'position() = '.$e;

после
}elseif('even' === $e){
$brackets[] = 'position() mod 2 = 0 and position() >= 0';

строка 167

Содержимое тега <script>

Здравствуйте!

Не получается вытащить содержимое тега <script>. На сколько я понял, внутренности тега должны попасть в #cdata-section, но внутри всегда пустой массив.
Пример html:

<script>writestat('show');</script>

Читаем:

$nakogiri->get('script')->toArray()

Получаем:

Array
(
    [0] => Array
        (
            [#cdata-section] => Array
                (
                    [0] => Array
                        (
                        )

                )

        )

)

Получения атрибутов тега работает корректно.

Скрипт не может корректно обработать большой объём входного html.

Привет.
Пытаюсь распарсить
http://ihtik.lib.ru/2011.07_ihtik_hudlit-ru/
Нужно выбрать все имена файлов.
Если делаю:
$elements = $saw->get('table[class=dirlistertable] tr')->toArray();
то падает с ошибкой
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 64 bytes) in /home/u1326/domains/khartn.name/public_html/dev/modules/nokogiri.php on line 217
.
Если же пытаюсь выполнить
$elements = $saw->get('table[class=dirlistertable] tr td:first-child')->toArray();
то падает в тайм-аут.

В первом варианте, когда не падает в тайм-аут, может стоило бы сделать вывод массива в файл, например, сериализовав его?
Тогда можно было бы избежать переполнения.
Или как-то разбивать данные, сбрасывая их на файловую подсистему.
Если есть ещё какие-то идеи - готов к обсуждению.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.