emanueleminotto/simple-html-dom
Simple HTML DOM parser for PHP. Provides a lightweight API to load HTML from strings/files/URLs, traverse and query elements, and extract text/attributes. Handy for scraping, data extraction, and quick HTML manipulation without a full browser.
Installation
composer require emanueleminotto/simple-html-dom
(Note: Due to the last release being in 2015, ensure your project’s PHP version is compatible—this package works with PHP 5.3+.)
Basic Usage Load HTML from a string or URL:
use SimpleHtmlDom\SimpleHtmlDom;
// From a string
$html = str_get_html('<html><body><h1>Hello</h1></body></html>');
echo $html->find('h1', 0)->plaintext; // "Hello"
// From a URL (with cURL fallback)
$html = file_get_html('https://example.com');
First Use Case: Extracting Links
$links = [];
foreach ($html->find('a') as $a) {
$links[] = $a->href;
}
Scraping Structured Data (Tables, Lists)
// Extract table rows
foreach ($html->find('table tr') as $row) {
$cells = $row->find('td');
// Process cells...
}
// Extract nested lists
$nestedItems = $html->find('ul li ul li');
Dynamic Content Handling
Use load() to refresh HTML (e.g., after AJAX updates):
$html->load('<div id="dynamic-content">Updated</div>');
echo $html->find('#dynamic-content', 0)->plaintext;
Attribute Manipulation
// Update an attribute
$img = $html->find('img', 0);
$img->src = 'new-image.jpg';
// Add a class
$div = $html->find('div', 0);
$div->class .= ' active';
Laravel Integration
$this->app->bind('html-dom', function () {
return new SimpleHtmlDom\SimpleHtmlDom();
});
use Illuminate\Console\Command;
class ScrapeCommand extends Command {
public function handle() {
$html = file_get_html('https://example.com');
// Scrape logic...
}
}
Caching Responses Cache parsed HTML to avoid repeated requests:
$cacheKey = 'scraped_html_' . md5('https://example.com');
$html = Cache::remember($cacheKey, now()->addHours(1), function () {
return file_get_html('https://example.com');
});
Deprecated Methods
str_get_html() directly; use the wrapper’s SimpleHtmlDom::load() or file_get_html().findAll()) may behave differently than expected—prefer find() for consistency.Memory Leaks
$html->clear();
unset($html);
SSL/HTTPS Issues
allow_url_fopen=1 in php.ini or manually set cURL options:
$context = stream_context_create([
'http' => ['header' => "User-Agent: Mozilla/5.0\r\n"]
]);
$html = file_get_html('https://example.com', false, $context);
XPath Limitations
DOMXPath or pre-filtering with CSS selectors.Encoding Issues
$html = str_get_html($content);
$html->find('meta', ['charset'])->content = 'UTF-8';
Inspect Nodes
Use ->outertext to debug node structures:
echo $html->find('div', 0)->outertext;
Selector Validation Test selectors in browser DevTools first. Example:
// Fails if no elements match
$elements = $html->find('.non-existent-class');
if (empty($elements)) {
throw new \RuntimeException("Selector not found");
}
Error Handling Wrap remote requests in try-catch:
try {
$html = file_get_html('https://example.com');
} catch (\Exception $e) {
Log::error("Scraping failed: " . $e->getMessage());
return null;
}
Custom Selector Helpers Extend the wrapper for Laravel-specific needs:
class LaravelHtmlDom extends SimpleHtmlDom {
public function findByDataAttribute($name, $value) {
return $this->find("[data-$name='$value']");
}
}
Event Dispatching Trigger events on DOM changes (e.g., for logging):
$html->on('nodeModified', function ($node) {
Log::debug("Node modified: " . $node->outertext);
});
Proxy Support Configure proxy settings for remote requests:
$html = file_get_html('https://example.com', false, [
'http' => [
'proxy' => 'tcp://proxy.example.com:8080',
'request_fulluri' => true,
]
]);
Performance Optimization
spatie/fork for concurrent scraping.How can I help you explore Laravel packages today?