Intereting Posts
Как вернуть true или false функцию ответа на данные ajax? Почему корзина пуста после добавления продукта preg_replace_callback требует, чтобы аргумент 2 был действительным обратным вызовом … Stuck! PHP-цикл для ввода пользователем Что означает «6k views» и как я могу отформатировать число в PHP? Как заменить переменную в запросе get в PHP? Вычисление строк PHP Внутренняя ошибка сервера (ошибка HTTP 500) после установки phpmyadmin в определенном домене Разбор больших текстовых файлов с PHP без убийства сервера Как установить динамический маршрут для использования slug в CodeIgniter? Многопользовательский поисковый запрос PHP MySQL с использованием опции / выбора тегов HTML-формы Как генерировать случайное 64-битное значение как десятичную строку в PHP Автоматическое соединение db в php? как проверить, является ли дата за три дня до сегодняшнего дня Как преобразовать данные latin1_swedish_ci в utf8_general_ci?

Извлечение данных из HTML с помощью PHP и xPath

Я пытаюсь извлечь данные с веб-страницы, чтобы вставить ее в базу данных. Данные, которые меня интересуют, находятся в div, которые имеют класс = «компания». На одной веб-странице есть 15 или менее div, и есть много страниц, с которых я пытаюсь извлечь эти данные. По этой причине я пытаюсь найти автоматическое решение для извлечения данных.

Деб с классом = «компания» выглядит следующим образом (на одной странице с разными данными есть 15 или менее divs):

<div class="company" id="company-6666"> <!-- EXTRACT 'company-6666' from id="company-6666" --> <div class="top clearfix"> <div class="name clearfix"> <h2> <a href="/company-name">Company Name</a>&nbsp; <!-- EXTRACT 'Company Name' from contents of A element and EXTRACT '/company-name' from href attribute --> <a href="/branches-list-link?parent_id=6666" class="branches">Branches <span>(5)</span></a> <!-- EXTRACT '/branches-list-link?parent_id=6666' from href attribute --> </h2> </div> </div> <div class="inner clearfix has-logo"> <div class="clearfix"> <div class="logo"> <a href="/company-name"> <img src="/graphics/company/logo/listing/123456.jpg?_ts=1365390237" border="0" alt="" /> <!-- EXTRACT '/graphics/company/logo/listing/123456.jpg?_ts=1365390237' from src attribute --> </a> </div> <div class="info"> <div class="address">StreetName 500, 7777 City, County</div> <!-- EXTRACT 'StreetName 500, 7777 City, County' from contents of class="address" div --> <div class="clearfix"> <div class="slogan">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ac condimentum mi.</div> <!-- EXTRACT 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ac condimentum mi.' from contents of class="slogan" div --> </div> </div> </div> <div class="actions-bar clearfix"> <ul> <li><span class="phone-number">6666666</span></li> <!-- EXTRACT '6666666' from contents of class="phone-number" div --> <li><a href="mailto:mail@mail.com" target="_blank" title="mail@mail.com" class="email">mail@mail.com</a></li> <!-- EXTRACT 'mail@mail.com' from contents of class="email" div --> <li><a href="http://www.webpage.com" target="_blank" title="www.webpage.com" class="redirect url">www.webpage.com</a></li> <!-- EXTRACT 'www.webpage.com' from contents of class="redirect url" div --> </ul> </div> </div> </div> 

До сих пор у меня есть следующий PHP-код (в $ output есть HTML-код веб-страницы):

 <?php $doc = new DomDocument(); @$doc->loadHTML($output); $doc->preserveWhiteSpace = false; $xpath = new DomXPath($doc); $elements = $xpath->query("//*[@class='company']"); if (!is_null($elements)) { foreach ($elements as $element) { echo $element->nodeValue; } } ?> 

Кажется, что он получает все 15 div с классом = «компания», но я понятия не имею, как извлечь ранее упомянутые (в комментариях HTML-кода) отдельные значения.

Каждый div (я говорю о div с class = "company") не имеет всех значений, записанных в блоке HTML. Так почему-то я должен сделать запрос, если конкретный div внутри div компании, где интересуются данные, существует, и если он существует, я должен проверить, не является ли он пустым (содержит текст между тегами или нет). Если он существует и не является пустым, я добавляю его к переменной.

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

 $result = array( // 1'st div's data [0] => 'company name' => 'company name', 'company link' => 'company link', 'company id' => 'company id', 'company branches' => 'branches link', 'company logo' => 'logo', 'company address' => 'address', 'company slogan' => 'slogan', 'company webpage' => 'webpage', 'company email' => 'email', 'company phone' => 'phone' // 2'nd div's data [1] => 'company name' => 'company name', 'company link' => 'company link', 'company id' => 'company id', 'company branches' => 'branches link', 'company logo' => 'logo', 'company address' => 'address', 'company slogan' => 'slogan', 'company webpage' => 'webpage', 'company email' => 'email', 'company phone' => 'phone' ... ) 

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

 Company company-6666: ->id ....... = "company-6666" -- string(@id) ->name ..... = "Company Name" -- .//a[1]/text() ->href ..... = "/company-name" -- .//a[1]/@href ->img ...... = "/graphics/company/logo/listing/123456.jpg?_ts=1365390237" -- .//img[1]/@src ->address .. = "StreetName 500, 7777 City, County" -- .//*[@class="address"]/text() ... 

Если вы обернете это в объекты, это довольно изящно использовать:

 $doc = new DOMDocument(); $doc->loadHTML($html); /* @var $companies DOMValueObject[] */ $companies = new Companies($doc); foreach ($companies as $company) { printf("Company %s:\n", $company->id); foreach ($company->getObjectProperties() as $name => $value) { $expression = $company->getPropertyExpression($name); printf(" ->%'.-10s = \"%s\" -- %s\n", $name.' ', $value, $expression); } } 

Это работает с DOMObjectCollection и DOMValueObject , определяя ваш собственный тип:

 class Companies extends DOMValueCollection { public function __construct(DOMDocument $doc) { parent::__construct($doc, '//*[@class="company"]'); } /** * @return DOMValueObject */ public function current() { $object = parent::current(); $object->defineProperty('id', 'string(@id)'); $object->defineProperty('name', './/a[1]/text()'); $object->defineProperty('href', './/a[1]/@href'); $object->defineProperty('img', './/img[1]/@src'); $object->defineProperty('address', './/*[@class="address"]/text()'); # ... add your definitions return $object; } } 

И для ваших требований к массиву существует метод getArrayCopy() :

 echo "\nGet Array Copy:\n\n"; print_r($companies->getArrayCopy()); 

Вывод:

 Get Array Copy: Array ( [0] => Array ( [id] => company-6666 [name] => Company Name [href] => /company-name [img] => /graphics/company/logo/listing/123456.jpg?_ts=1365390237 [address] => StreetName 500, 7777 City, County ) ) 

Чтобы проверить, существует ли узел, убедитесь, что свойство length равно 1 в возвращаемом запросе:

 if ($company_name->length == 1) { $object->company_name = trim($company_name->item(0)->nodeValue); }