IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
michales
Člen
Avatar
michales:26.2.2015 16:46

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
Odpovídá na michales
Neaktivní uživatel:26.2.2015 17:11

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
Neaktivní uživatelský účet
Avatar
shaman
Člen
Avatar
Odpovídá na michales
shaman:26.2.2015 17:13

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:26.2.2015 17:25

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í
+2,50 Kč
Ř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:26.2.2015 17:28

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:26.2.2015 17:28

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:26.2.2015 17:36

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:26.2.2015 17:40

žá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:26.2.2015 17:46

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:26.2.2015 17:49

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:26.2.2015 17:51

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:26.2.2015 17:54
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:26.2.2015 17:56

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:26.2.2015 18:18

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:26.2.2015 18:23

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:26.2.2015 19:07

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
26.2.2015 19:07
try {...} catch (Exception ignored) { echo " ¯\_(ツ)_/¯ "; }
Avatar
michales
Člen
Avatar
Odpovídá na shaman
michales:26.2.2015 19:13

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:26.2.2015 20:22

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:26.2.2015 20:28

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
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:27.2.2015 8:02

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.