Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Parsowanie wielkiego pliku html, Regexp, XML ?? jak do tego lepiej podejść ??
metoda
post 2.03.2010, 15:23:28
Post #1





Grupa: Zarejestrowani
Postów: 38
Pomógł: 0
Dołączył: 22.12.2008

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
szagi3891
post 5.03.2010, 20:31:48
Post #2





Grupa: Zarejestrowani
Postów: 109
Pomógł: 9
Dołączył: 12.03.2007
Skąd: kraków/tarnobrzeg/baranów/suchorzów

Ostrzeżenie: (0%)
-----


  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ć ?


--------------------

Każdy z was jest łodzią w której
Może się z potopem mierzyć
Cało wyjść z burzowej chmury
Musi tylko w to uwierzyć!
Go to the top of the page
+Quote Post
Pilsener
post 6.03.2010, 13:01:51
Post #3





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 18.07.2025 - 11:05