deepslam/content-parser
Laravel 5 package to extract a web page’s main content and title using automatic algorithms. Supports Graby (default) and Mercury API parsers, with an extensible architecture and optional HTML cleanup (remove CSS/style attrs, strip tags) for clean output.
Installation
composer require deepslam/content-parser
Add to composer.json if not auto-discovered:
"autoload": {
"psr-4": {
"App\\": "app/",
"Deepslam\\ContentParser\\": "vendor/deepslam/content-parser/src/"
}
}
Run composer dump-autoload.
First Use Case Parse a URL’s main content:
use Deepslam\ContentParser\ContentParser;
$parser = new ContentParser();
$content = $parser->parse('https://example.com');
echo $content->getContent(); // Returns the extracted text
Key Classes to Explore
ContentParser: Main class for parsing.Content: Holds parsed results (title, content, images, etc.).Parser\*: Concrete parsers (e.g., Parser\DefaultParser, Parser\MediumParser).Basic Parsing
$parser = new ContentParser();
$content = $parser->parse('https://blog.example.com/post');
$title = $content->getTitle();
$text = $content->getContent();
Custom Parser Selection Override default parser for specific domains:
$parser = new ContentParser();
$parser->setParser('medium', new \Deepslam\ContentParser\Parser\MediumParser());
$content = $parser->parse('https://medium.com/...');
Batch Processing Useful for scraping multiple pages (e.g., RSS feeds or sitemaps):
$urls = ['url1', 'url2', 'url3'];
$results = [];
foreach ($urls as $url) {
$results[$url] = (new ContentParser())->parse($url);
}
Integration with Laravel
// app/Providers/ContentParserServiceProvider.php
public function register() {
$this->app->singleton(ContentParser::class, function ($app) {
return new ContentParser();
});
}
// app/Facades/ContentParserFacade.php
public static function parse($url) {
return app(ContentParser::class)->parse($url);
}
Storing Results Save parsed content to a database (e.g., using Eloquent):
$parsed = (new ContentParser())->parse('https://example.com');
$post = new Post();
$post->title = $parsed->getTitle();
$post->content = $parsed->getContent();
$post->save();
Outdated Dependencies
guzzlehttp/guzzle: ~5.0).Fragile Parsing Logic
try {
$content = $parser->parse($url);
} catch (\Exception $e) {
$parser->setParser('default', new \Deepslam\ContentParser\Parser\DefaultParser());
$content = $parser->parse($url);
}
Rate Limiting
sleep(1); // 1-second delay between requests
Encoding Issues
ISO-8859-1). Normalize output:
$content = mb_convert_encoding($content, 'UTF-8', 'auto');
Inspect Parsed HTML Dump the raw HTML before parsing to debug selectors:
$html = file_get_contents('https://example.com');
// Manually inspect $html or use `var_dump($parser->getDom())`.
Log Failures Track URLs that fail parsing:
try {
$content = $parser->parse($url);
} catch (\Exception $e) {
Log::error("Failed to parse $url: " . $e->getMessage());
}
Custom Parsers
Extend \Deepslam\ContentParser\Parser\AbstractParser to handle niche sites:
class CustomParser extends AbstractParser {
protected function parse() {
// Custom logic (e.g., XPath queries)
return $this->extractContent();
}
}
Pre/Post-Processing Hook into the pipeline:
$parser = new ContentParser();
$parser->setPreParser(function ($html) {
// Modify HTML before parsing (e.g., remove ads)
return $html;
});
$parser->setPostParser(function ($content) {
// Clean up text (e.g., remove extra whitespace)
return trim($content);
});
Caching Cache parsed results to avoid repeated requests:
$cacheKey = 'parsed_content_' . md5($url);
if (Cache::has($cacheKey)) {
$content = Cache::get($cacheKey);
} else {
$content = (new ContentParser())->parse($url);
Cache::put($cacheKey, $content, now()->addHours(1));
}
$parser->setClient(new \GuzzleHttp\Client([
'headers' => ['User-Agent' => 'Mozilla/5.0']
]));
How can I help you explore Laravel packages today?