mirror of
https://github.com/manualdousuario/marreta.git
synced 2025-09-02 02:30:20 +00:00
ajustes e melhorias
This commit is contained in:
parent
69fff02d3f
commit
4981232716
1 changed files with 150 additions and 164 deletions
|
@ -110,13 +110,13 @@ class URLAnalyzer
|
|||
return $this->cache->get($cleanUrl);
|
||||
}
|
||||
|
||||
$domain = parse_url($cleanUrl, PHP_URL_HOST);
|
||||
$domain = preg_replace('/^www\./', '', $domain);
|
||||
$host = parse_url($cleanUrl, PHP_URL_HOST);
|
||||
$host = preg_replace('/^www\./', '', $host);
|
||||
|
||||
// Verificação de domínios bloqueados
|
||||
foreach (BLOCKED_DOMAINS as $blockedDomain) {
|
||||
// Verifica apenas correspondência exata do domínio
|
||||
if ($domain === $blockedDomain) {
|
||||
if ($host === $blockedDomain) {
|
||||
$error = 'Este domínio está bloqueado para extração.';
|
||||
$this->logError($cleanUrl, $error);
|
||||
throw new Exception($error);
|
||||
|
@ -127,10 +127,11 @@ class URLAnalyzer
|
|||
|
||||
// Primeiro, tenta buscar o conteúdo diretamente
|
||||
try {
|
||||
$content = $this->fetchContent($url);
|
||||
$content = $this->fetchContent($url, $host);
|
||||
} catch (Exception $e) {
|
||||
// Se falhar, registra o erro de busca direta
|
||||
$this->logError($url, "Direct fetch error: " . $e->getMessage());
|
||||
$content = null;
|
||||
}
|
||||
|
||||
// Se a busca direta falhar, tenta o Wayback Machine
|
||||
|
@ -144,12 +145,11 @@ class URLAnalyzer
|
|||
}
|
||||
|
||||
if (!empty($content)) {
|
||||
$content = $this->processContent($content, $domain, $cleanUrl);
|
||||
$content = $this->processContent($content, $host, $cleanUrl);
|
||||
$this->cache->set($cleanUrl, $content);
|
||||
return $content;
|
||||
}
|
||||
|
||||
return null;
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -212,15 +212,11 @@ class URLAnalyzer
|
|||
* Realiza requisição HTTP usando Curl Class
|
||||
*
|
||||
* @param string $url URL para requisição
|
||||
* @return string Conteúdo obtido
|
||||
* @throws Exception Em caso de erro na requisição
|
||||
* @return array Resultado da requisição com conteúdo e código HTTP
|
||||
*/
|
||||
private function fetchContent($url)
|
||||
private function fetchContent($url, $host)
|
||||
{
|
||||
$parsedUrl = parse_url($url);
|
||||
$host = $parsedUrl['host'];
|
||||
|
||||
$domainRules = $this->getDomainRules(parse_url($url, PHP_URL_HOST));
|
||||
$domainRules = $this->getDomainRules($host);
|
||||
|
||||
// Obtém a configuração do user agent
|
||||
$curl = new Curl();
|
||||
|
@ -323,78 +319,6 @@ class URLAnalyzer
|
|||
return $this->rules->getDomainRules($domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove classes específicas de um elemento
|
||||
*
|
||||
* @param DOMElement $element Elemento DOM
|
||||
* @param array $classesToRemove Classes a serem removidas
|
||||
*/
|
||||
private function removeClassNames($element, $classesToRemove)
|
||||
{
|
||||
if (!$element->hasAttribute('class')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$classes = explode(' ', $element->getAttribute('class'));
|
||||
$newClasses = array_filter($classes, function ($class) use ($classesToRemove) {
|
||||
return !in_array(trim($class), $classesToRemove);
|
||||
});
|
||||
|
||||
if (empty($newClasses)) {
|
||||
$element->removeAttribute('class');
|
||||
} else {
|
||||
$element->setAttribute('class', implode(' ', $newClasses));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Corrige URLs relativas em um documento DOM
|
||||
*
|
||||
* @param DOMDocument $dom Documento DOM
|
||||
* @param DOMXPath $xpath Objeto XPath
|
||||
* @param string $baseUrl URL base para correção
|
||||
*/
|
||||
private function fixRelativeUrls($dom, $xpath, $baseUrl)
|
||||
{
|
||||
$parsedBase = parse_url($baseUrl);
|
||||
$baseHost = $parsedBase['scheme'] . '://' . $parsedBase['host'];
|
||||
|
||||
$elements = $xpath->query("//*[@src]");
|
||||
if ($elements !== false) {
|
||||
foreach ($elements as $element) {
|
||||
if ($element instanceof DOMElement) {
|
||||
$src = $element->getAttribute('src');
|
||||
if (strpos($src, 'base64') !== false) {
|
||||
continue;
|
||||
}
|
||||
if (strpos($src, 'http') !== 0 && strpos($src, '//') !== 0) {
|
||||
$src = ltrim($src, '/');
|
||||
$element->setAttribute('src', $baseHost . '/' . $src);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$elements = $xpath->query("//*[@href]");
|
||||
if ($elements !== false) {
|
||||
foreach ($elements as $element) {
|
||||
if ($element instanceof DOMElement) {
|
||||
$href = $element->getAttribute('href');
|
||||
if (strpos($href, 'mailto:') === 0 ||
|
||||
strpos($href, 'tel:') === 0 ||
|
||||
strpos($href, 'javascript:') === 0 ||
|
||||
strpos($href, '#') === 0) {
|
||||
continue;
|
||||
}
|
||||
if (strpos($href, 'http') !== 0 && strpos($href, '//') !== 0) {
|
||||
$href = ltrim($href, '/');
|
||||
$element->setAttribute('href', $baseHost . '/' . $href);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processa o conteúdo HTML aplicando regras do domínio
|
||||
*
|
||||
|
@ -403,7 +327,7 @@ class URLAnalyzer
|
|||
* @param string $url URL completa
|
||||
* @return string Conteúdo processado
|
||||
*/
|
||||
private function processContent($content, $domain, $url)
|
||||
private function processContent($content, $host, $url)
|
||||
{
|
||||
$dom = new DOMDocument();
|
||||
$dom->preserveWhiteSpace = true;
|
||||
|
@ -435,19 +359,10 @@ class URLAnalyzer
|
|||
// Sempre aplica a correção de URLs relativas
|
||||
$this->fixRelativeUrls($dom, $xpath, $url);
|
||||
|
||||
$domainRules = $this->getDomainRules($domain);
|
||||
if ($domainRules !== null) {
|
||||
$domainRules = $this->getDomainRules($host);
|
||||
if (isset($domainRules['customStyle'])) {
|
||||
$styleElement = $dom->createElement('style');
|
||||
$styleContent = '';
|
||||
foreach ($domainRules['customStyle'] as $selector => $rules) {
|
||||
if (is_array($rules)) {
|
||||
$styleContent .= $selector . ' { ' . implode('; ', $rules) . ' } ';
|
||||
} else {
|
||||
$styleContent .= $selector . ' { ' . $rules . ' } ';
|
||||
}
|
||||
}
|
||||
$styleElement->appendChild($dom->createTextNode($styleContent));
|
||||
$styleElement->appendChild($dom->createTextNode($domainRules['customStyle']));
|
||||
$dom->getElementsByTagName('head')[0]->appendChild($styleElement);
|
||||
}
|
||||
|
||||
|
@ -518,7 +433,6 @@ class URLAnalyzer
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$elements = $xpath->query("//*[@style]");
|
||||
if ($elements !== false) {
|
||||
|
@ -535,7 +449,7 @@ class URLAnalyzer
|
|||
$body = $xpath->query('//body')->item(0);
|
||||
if ($body) {
|
||||
$marretaDiv = $dom->createElement('div');
|
||||
$marretaDiv->setAttribute('style', 'z-index: 99999; position: fixed; bottom: 0; right: 4px; background: rgb(37,99,235); color: #fff; font-size: 13px; line-height: 1em; padding: 6px; margin: 0px; overflow: hidden; border-top-left-radius: 3px; border-top-right-radius: 3px; font-family: Tahoma, sans-serif;');
|
||||
$marretaDiv->setAttribute('style', 'z-index: 99999; position: fixed; top: 0; right: 4px; background: rgb(37,99,235); color: #fff; font-size: 13px; line-height: 1em; padding: 6px; margin: 0px; overflow: hidden; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; font-family: Tahoma, sans-serif;');
|
||||
$marretaHtml = $dom->createDocumentFragment();
|
||||
$marretaHtml->appendXML('Chapéu de paywall é <a href="'.SITE_URL.'" style="color: #fff; text-decoration: underline; font-weight: bold;" target="_blank">Marreta</a>!');
|
||||
$marretaDiv->appendChild($marretaHtml);
|
||||
|
@ -544,4 +458,76 @@ class URLAnalyzer
|
|||
|
||||
return $dom->saveHTML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove classes específicas de um elemento
|
||||
*
|
||||
* @param DOMElement $element Elemento DOM
|
||||
* @param array $classesToRemove Classes a serem removidas
|
||||
*/
|
||||
private function removeClassNames($element, $classesToRemove)
|
||||
{
|
||||
if (!$element->hasAttribute('class')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$classes = explode(' ', $element->getAttribute('class'));
|
||||
$newClasses = array_filter($classes, function ($class) use ($classesToRemove) {
|
||||
return !in_array(trim($class), $classesToRemove);
|
||||
});
|
||||
|
||||
if (empty($newClasses)) {
|
||||
$element->removeAttribute('class');
|
||||
} else {
|
||||
$element->setAttribute('class', implode(' ', $newClasses));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Corrige URLs relativas em um documento DOM
|
||||
*
|
||||
* @param DOMDocument $dom Documento DOM
|
||||
* @param DOMXPath $xpath Objeto XPath
|
||||
* @param string $baseUrl URL base para correção
|
||||
*/
|
||||
private function fixRelativeUrls($dom, $xpath, $baseUrl)
|
||||
{
|
||||
$parsedBase = parse_url($baseUrl);
|
||||
$baseHost = $parsedBase['scheme'] . '://' . $parsedBase['host'];
|
||||
|
||||
$elements = $xpath->query("//*[@src]");
|
||||
if ($elements !== false) {
|
||||
foreach ($elements as $element) {
|
||||
if ($element instanceof DOMElement) {
|
||||
$src = $element->getAttribute('src');
|
||||
if (strpos($src, 'base64') !== false) {
|
||||
continue;
|
||||
}
|
||||
if (strpos($src, 'http') !== 0 && strpos($src, '//') !== 0) {
|
||||
$src = ltrim($src, '/');
|
||||
$element->setAttribute('src', $baseHost . '/' . $src);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$elements = $xpath->query("//*[@href]");
|
||||
if ($elements !== false) {
|
||||
foreach ($elements as $element) {
|
||||
if ($element instanceof DOMElement) {
|
||||
$href = $element->getAttribute('href');
|
||||
if (strpos($href, 'mailto:') === 0 ||
|
||||
strpos($href, 'tel:') === 0 ||
|
||||
strpos($href, 'javascript:') === 0 ||
|
||||
strpos($href, '#') === 0) {
|
||||
continue;
|
||||
}
|
||||
if (strpos($href, 'http') !== 0 && strpos($href, '//') !== 0) {
|
||||
$href = ltrim($href, '/');
|
||||
$element->setAttribute('href', $baseHost . '/' . $href);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue