Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Parsowanie wielkiego pliku html
Forum PHP.pl > Forum > PHP
metoda
Witam. Posiadam plik html, który po eliminacji niepotrzebnych znaczników, składa sie głownie z <div> i <span>. Div'y i span'y mają jakieś atrybuty bądź nie. Wygląda to mniej więcej tak:

  1.  
  2. <div><span>asd</span><span class="smaller bold">(192206)</span></div>
  3. <div class="mg1"><span>ZXC</span><span class="smaller">(36137)</span></div>
  4. <div class="mg1"><span>sadf</span><span class="xtrasmall">(9987)</span></div>
  5. <div class="mg2"><span>zxC</span><span class="ultrasmall">(382)</span></div>
  6. <div class="mg3"><span>zXC</span><span class="ultrasmall">(6733)</span></div>
  7.  
  8. <div><span>xyz</span><span class="smaller bold">(192206)</span></div>
  9. <div class="mg1"><span>asd</span><span class="smaller">(36137)</span></div>
  10. <div class="mg2"><span>dfg</span><span class="xtrasmall">(9987)</span></div>
  11. <div class="mg2"><span>weqr</span><span class="ultrasmall">(382)</span></div>
  12. <div class="mg3"><span>asdf</span><span class="ultrasmal

Jest to pewien katalog kategorii. W <div> jest kategoria głowna, a w <div class="mg1"> jest kategoria podrzędna. Reszta div'ów mnie nie interesuje. Muszę powyciągać tylko te dwa div'y a dokładnie <span> z tych divów.
Co najgorsze chyba, to fakt taki że ten plik html zajmuje jakies 4mln znaków.

Próbowałem podejść do tego wyrażenie regularnym:
  1. preg_match_all("#<div([^>]*)>(.*?)</div>#s",$input, $out);

ale wtedy pobiera wszystkie div'y.

Udało mi się to w miarę osiągnąc poprzez XML:
  1.  
  2. function parse_cats(){
  3.  
  4. $categories=array();
  5.  
  6. $input=file_get_contents('index.html');
  7.  
  8. $div_input=strip_tags($input,'<div></div><span></span>');
  9. //$out_clear=utf8_encode($div_input);
  10.  
  11. $dom=new DOMDocument();
  12. $dom->loadHTML($div_input);
  13. $dom->preserveWhiteSpace=false;
  14. $sxml = simplexml_import_dom($dom);
  15. $elem=$sxml->body->div;
  16. $_flag=false;
  17. $outxml="";
  18. foreach ($elem as $node){
  19.  
  20. if (!$node->attributes()){
  21. if ($_flag){
  22. $outxml.='</cat>';
  23. }
  24. $outxml.='<cat name="'.$node->span[0].'">';
  25. $_flag=false;
  26.  
  27. }else{
  28. foreach ($node->attributes() as $att=>$val){
  29. if ($att=="class"&&$val=="mg1"){
  30. $_flag=true;
  31. $outxml.='<subcat>'.$node->span[0].'</subcat>';
  32.  
  33. }
  34. }
  35. }
  36. }
  37. $outxml='<categories>'.$outxml.'</cat></categories>';
  38. $out=simplexml_load_string($outxml);
  39. $out->asXML('index_parsed.xml');
  40.  
  41.  
  42. }
  43.  
  44. parse_cats();
  45.  


Funkcja ta działa dla małego pliku index.html, niestety nie działa przy większym.
Dostaję błąd:

error: Excessive depth in document: 256 use XML_PARSE_HUGE option

Co radzicie questionmark.gif
szagi3891
  1. $plik = preg_replace('#^\s+#si' , "" , $plik);
  2. $plik = preg_replace('#\n\s+#si', "\n", $plik);
  3.  
  4. $plik = preg_replace('#\s+$#si' , "" , $plik);
  5. $plik = preg_replace('#\s+\n#si', "\n", $plik);
  6.  
  7. $plik = preg_replace('#^\<[^>]+\>#si' , "" , $plik);
  8. $plik = preg_replace('#\n\<[^>]+\>#si', "\n", $plik);
  9.  
  10. $plik = preg_replace('#\<[^>]+\>$#si' , "" , $plik);
  11. $plik = preg_replace('#\<[^>]+\>\n#si', "\n", $plik);



Tak to możesz zrobić za pomocą wyrażeń regularnych. W zaproponowanym kodzie stopniowo wycinane jest to co jest zbędne. Oczywiście pewnie się da stworzyć jedno większe wyrażenie ale nie chciało mi się zbytnio kombinować.

Spróbuj tego. Czy to jest jednorazowa operacja przy przetworzeniu tego pliku którą musisz wykonać ?
Pilsener
Pliki obrabia się linia po linii:
  1. $uchwyt = fopen ("/tmp/inputfile.txt", "r");
  2. while (!feof($uchwyt)) {
  3. $linia = rtrim(fgets($uchwyt));
  4. //tu kod obrabiający plik
  5. echo $linia.'<br />';
  6. }
  7. fclose ($uchwyt);
- ewentualnie co ileś bajtów.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.