Avatar
michales
Člen
Avatar
michales:

Dobrý den,
prosím o radu.
Potřebuji vytáhnout vše co je v

<div id="lyrics-body-text">nějaký text</div>

Mám to takto:

preg_match('/<div id=\"lyrics-body-text\">(.*)<\/div>/', $obsah, $match);

ale bohužel mi to nic nevytáhne.
Jak to prosím má být správně?
Díky.

Odpovědět 26.2.2015 16:46
"Cíle by měly být třešínky na dortech, ne na hromadách hoven."
Avatar
Fredep
Redaktor
Avatar
Odpovídá na michales
Fredep:

Ahoj, v paternech se moc nevyznám, ale když jsem to zkusil spustit, tak mi to fungovalo. Do proměnné $match se mi uložily dvě hodnoty.

Array
(
    [0] => <div id="lyrics-body-text">nějaký text</div>
    [1] => nějaký text
)
Nahoru Odpovědět 26.2.2015 17:11
Týmová práce je důležitá proto, aby bylo možno obvinit z neúspěchu někoho jiného.
Avatar
shaman
Člen
Avatar
Odpovídá na michales
shaman:

Regex mas spravne,
Ak $obsah nemas prazdny, tak musis mat vsetko v poli $match. Vies nam ukazat var_dump tvojho $obsah-u ?

Nahoru Odpovědět 26.2.2015 17:13
try {...} catch (Exception ignored) { echo " ¯\_(ツ)_/¯ "; }
Avatar
shaman
Člen
Avatar
shaman:

Osobne, zvolil by som iny pristup, ale ten bude fungovat len ak je html kod je validny:

$dom = new DOMDocument();

$dom->loadHTML($obsah);

$xpath = new DOMXPath($dom);
$obsah = $xpath->query('//div[id="lyrics-body-text"]');

Vytvoris is DOM objejt a do neho si nacitas obsah. Objekt sa postara o parsovanie. A potom sa pytas DOM objektu na div s id=lyrics-body-text. Je to podbne ako PDO, ktoreho sa pytas rozne query do DB.

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět 26.2.2015 17:25
try {...} catch (Exception ignored) { echo " ¯\_(ツ)_/¯ "; }
Avatar
Tomáš123
Člen
Avatar
Odpovídá na michales
Tomáš123:

V zápise nie je potrebné escapovať úvodzovky.

Nahoru Odpovědět 26.2.2015 17:28
Keby nebolo Internetu Exploreru, nebolo by dnešného internetu.
Avatar
michales
Člen
Avatar
Odpovídá na shaman
michales:

Nejsem moc znalý tak sem vložím celou funkci:

function ziskatlyrics($url) {
  $platnost = 30; // 60 s
  $soubor = urlencode($url);

  if (
      ! file_exists($soubor) ||
      (filemtime($soubor) <= time() - $platnost)
     ) {
    // obsah se musí stáhnout z cizí URL
    $obsah = file_get_contents($url);
    preg_match('/<div id=\"lyrics-body-text\">(.*)<\/div>/', $obsah, $match);
    // uložení obsahu do cache
    file_put_contents("soubory/".$soubor, $match[1]);
  }
  // obsah je určitě v cachi
  return file_get_contents("soubory/".$soubor);
}

echo ziskatlyrics("http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html");
echo "http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html";
Nahoru Odpovědět 26.2.2015 17:28
"Cíle by měly být třešínky na dortech, ne na hromadách hoven."
Avatar
Tomáš123
Člen
Avatar
Odpovídá na michales
Tomáš123:

Funkcia file_get_cotents nevie stiahnuť obsah z cudzej URL. To pravdepodobne vedie k nečakanému výsledku regulárneho výrazu, čo znefunkční file_put_contents (nehovoriac o tom, že ak súbor neexistuje z funkcie sa nevráti očakávaný obsah).

Zapni si vypisovanie chýb a skopíruj sem tie hlásenia.

Editováno 26.2.2015 17:38
Nahoru Odpovědět 26.2.2015 17:36
Keby nebolo Internetu Exploreru, nebolo by dnešného internetu.
Avatar
michales
Člen
Avatar
Odpovídá na Tomáš123
michales:

žádné chyby to neháže, a script bych řekl že jefunkční, protože např. toto funguje:

function ziskatlyrics($url) {
  $platnost = 30; // 60 s
  $soubor = urlencode($url);

  if (
      ! file_exists($soubor) ||
      (filemtime($soubor) <= time() - $platnost)
     ) {
    // obsah se musí stáhnout z cizí URL
    $obsah = file_get_contents($url);
    preg_match('/<pre.*?>(.*)<\/pre>/', $obsah, $match);
    // uložení obsahu do cache
    file_put_contents($soubor, $match[1]);
  }
  // obsah je určitě v cachi
  return file_get_contents($soubor);
}
echo ziskatlyrics(
  "http://www.classic-country-song-lyrics.com/babywontyoucomeouttonightlyricschords.html"
);
Nahoru Odpovědět 26.2.2015 17:40
"Cíle by měly být třešínky na dortech, ne na hromadách hoven."
Avatar
Tomáš123
Člen
Avatar
Odpovídá na michales
Tomáš123:

To znamená, že sa požadovaný obsah uloží do súboru?

Existuje na tej druhej stránke <div id="lyrics-body-text">?

EDIT: Odober zo zápisu v regexe to escapovanie. Keď nie je potrebné, tak sa zoberie a na stránke sa hľadá prvok <div id=\"lyrics-body-text\">, ktorý sa nenájde.

Editováno 26.2.2015 17:48
Nahoru Odpovědět 26.2.2015 17:46
Keby nebolo Internetu Exploreru, nebolo by dnešného internetu.
Avatar
michales
Člen
Avatar
Odpovídá na Tomáš123
michales:

Text potřebuji vytáhnout z této stránky: http://www.metrolyrics.com/…-denver.html
Ano měl by se uložit do souboru.
A na této stránce existuje <div id="lyrics-body-text">

Ani když použiji

preg_match('/<div id="lyrics-body-text">(.*)<\/div>/', $obsah, $match);

nic se nestane

Editováno 26.2.2015 17:50
Nahoru Odpovědět 26.2.2015 17:49
"Cíle by měly být třešínky na dortech, ne na hromadách hoven."
Avatar
Tomáš123
Člen
Avatar
Odpovídá na michales
Tomáš123:

Vlož do kódu pod inicializáciu premennej $obsah:

var_dump($obsah)

Čo to vypíše?

Editováno 26.2.2015 17:54
Nahoru Odpovědět 26.2.2015 17:51
Keby nebolo Internetu Exploreru, nebolo by dnešného internetu.
Avatar
Tomáš123
Člen
Avatar
Tomáš123:
var_dump($obsah);

prepáč.

Editováno 26.2.2015 17:55
Nahoru Odpovědět 26.2.2015 17:54
Keby nebolo Internetu Exploreru, nebolo by dnešného internetu.
Avatar
michales
Člen
Avatar
Odpovídá na Tomáš123
michales:

Při var_dump($obsah); to načetlo celou tu stránku a v levém horním rohu je:string(101865) "

Nahoru Odpovědět 26.2.2015 17:56
"Cíle by měly být třešínky na dortech, ne na hromadách hoven."
Avatar
shaman
Člen
Avatar
Odpovídá na michales
shaman:

Skusal si uz toto?

function ziskatlyrics($url)
{
    $dom = new DOMDocument();
    $dom->loadHTMLFile($url);
    $xpath = new DOMXPath($dom);
    $obsah = $xpath->query('//div[id="lyrics-body-text"]');
    return $obsah;
}

echo ziskatlyrics("http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html");
echo "http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html";
Editováno 26.2.2015 18:18
Nahoru Odpovědět 26.2.2015 18:18
try {...} catch (Exception ignored) { echo " ¯\_(ツ)_/¯ "; }
Avatar
michales
Člen
Avatar
Odpovídá na shaman
michales:

Zkoušel a hodí to chybu Catchable fatal error: Object of class DOMNodeList could not be converted to string in na řádku

echo ziskatlyrics("http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html");
Nahoru Odpovědět 26.2.2015 18:23
"Cíle by měly být třešínky na dortech, ne na hromadách hoven."
Avatar
shaman
Člen
Avatar
Odpovídá na michales
shaman:

aha, no tak to preto lebo je DOM je pokazeny, html stranka je prepletena scriptami a podobne.
Ja nerad pouzivam regularne vyrazy lebo vzdy nieco nefunguje ako ma. Dalsie riesenie ma napada rozdelit ho funkciou explode

function ziskatlyrics($url)
{
    $content = file_get_contents($url);
    $first_step = explode( '<div id="lyrics-body-text">' , $content );
    $second_step = explode("</div>" , $first_step[1] );

    $obsah = $second_step[0];

    return $obsah;
}

echo ziskatlyrics("http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html");
echo "http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html";

EDIT: toto ale nebude fungovat spravne ak tvoj <div> obsahuje vo vnutri dalsie divy a ukoncenia divov, lebo ti to sekne tam. :(

Editováno 26.2.2015 19:10
Nahoru Odpovědět  +1 26.2.2015 19:07
try {...} catch (Exception ignored) { echo " ¯\_(ツ)_/¯ "; }
Avatar
michales
Člen
Avatar
Odpovídá na shaman
michales:

Moc ti děkuji za tvůj čas. Velice si mi pomohl. Žádné jiné divy tam nejsou takže je to v pořádku. Ještě jednou díky.

Nahoru Odpovědět 26.2.2015 19:13
"Cíle by měly být třešínky na dortech, ne na hromadách hoven."
Avatar
michales
Člen
Avatar
Odpovídá na shaman
michales:

Jenom mi teď nastal problém při načítaní ajaxem. Pokud si otevřu tento samotný script v pořádku se text zobrazí. Pokud ho zavolám ajaxem tak se bohužel text nezobrazí

Nahoru Odpovědět 26.2.2015 20:22
"Cíle by měly být třešínky na dortech, ne na hromadách hoven."
Avatar
1Pupik1989
Člen
Avatar
Odpovídá na shaman
1Pupik1989:

Je to proto, protože vracíš element a ne text. DOMNodeList nemá definovanout metodu toString, takže to vrátí chybu. Navíc DOMXPath je zbytečný, pokud jdou využít nativní metody DOMDocumentu.

function ziskatlyrics($url){
  $dom = new DOMDocument();
  $dom->loadHTMLFile($url);

  $lyrics_element = $dom->getElementById('lyrics-body-text');

  return $lyrics_element ? $lyrics_element->textContent : '';
}

echo ziskatlyrics("http://www.metrolyrics.com/take-me-home-country-roads-lyrics-john-denver.html");
 
Nahoru Odpovědět  +1 26.2.2015 20:28
Avatar
michales
Člen
Avatar
Nahoru Odpovědět 27.2.2015 4:23
"Cíle by měly být třešínky na dortech, ne na hromadách hoven."
Avatar
1Pupik1989
Člen
Avatar
1Pupik1989:

To je chyba DOMDocumentu, protože takové HTML5 neovládá vůbec. Takže máš 3 možnosti:

  1. Potlačit výpis varování.
  2. Použít alternativní DOM Parser.
  3. Najít element přes regulární výraz (s rekurzí nebo bez). Tato varianta je nejnáchylnější na chyby, ale víceméně jednoduchý.
 
Nahoru Odpovědět 27.2.2015 8:02
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 21 zpráv z 21.