[Q]Парсинг большой бд

Discussion in 'PHP' started by #Wolf#, 16 Mar 2009.

  1. #Wolf#

    #Wolf# Elder - Старейшина

    Joined:
    26 Mar 2008
    Messages:
    375
    Likes Received:
    166
    Reputations:
    16
    Что имеем:
    1) большую бд (порядка) 300 метров
    2) 63к записей.

    Значит в каждой записи имеется несколько ссылок
    В целях сео оптимизации хотелось бы превратить кликабельные ссылки в простой текст
    -->
    как бы с небольшими юд это будет достаточно просто сделать, но .... это не мой случай.
    Хотел бы выслушать ваши предложения
     
  2. ph1l1ster

    ph1l1ster Elder - Старейшина

    Joined:
    11 Mar 2008
    Messages:
    396
    Likes Received:
    153
    Reputations:
    19
    можно и так:

    Code:
    #!usr/bin/perl
    open(DB, "base.txt");
    @db = <DB>;
    close(DB);
    open(PARSED, ">>parsed.txt");
    foreach $db (@db)
    {
    ($a, $url, $b) = split("\"",$db);
    chomp($url);
    print PARSED "$url\n";
    tr/a-zA-Z//cd
    }
    close(PARSED);
    
    и больше размеры парсил
     
    #2 ph1l1ster, 16 Mar 2009
    Last edited: 16 Mar 2009
  3. Gray_Wolf

    Gray_Wolf Active Member

    Joined:
    7 Mar 2009
    Messages:
    377
    Likes Received:
    135
    Reputations:
    10
    Парсили 2 милиона записей и всё в порядке :)

    Способ 1:
    Слить базу на локальный комп и там распарсить.
    Способ 2:
    Если локальный комп слабый, то слить базу и распарсить через C++.
    Способ 3:
    Распарсить удалённо используя C++.
     
  4. rcc0023

    rcc0023 Elder - Старейшина

    Joined:
    3 Jul 2008
    Messages:
    100
    Likes Received:
    6
    Reputations:
    0
    Вполне можно и на php с использованием sleep(1)
     
  5. -=Static=-

    -=Static=- Banned

    Joined:
    12 Nov 2006
    Messages:
    201
    Likes Received:
    40
    Reputations:
    0
    set_time_limit(0)
    SET TRANSATION
    и поехал че хочешь с ней ковырять...заливай на удаленную машину, запускай и иди курить, придешь - соптимизируется... У нас на работе для 2-3кк записей на ночь оставляли
     
  6. #Wolf#

    #Wolf# Elder - Старейшина

    Joined:
    26 Mar 2008
    Messages:
    375
    Likes Received:
    166
    Reputations:
    16
    ах да..кто не понял база - мускул
    UPD// набросать кто может на php?
     
    #6 #Wolf#, 16 Mar 2009
    Last edited: 16 Mar 2009
    1 person likes this.
  7. #Wolf#

    #Wolf# Elder - Старейшина

    Joined:
    26 Mar 2008
    Messages:
    375
    Likes Received:
    166
    Reputations:
    16
    PHP:
    $result mysql_query("SELECT * FROM posts LIMIT 10")or die("бля: " mysql_error()); 

    while (
    $row=mysql_fetch_array($result)) 
    {  
    echo 
    "$row[full_news]";
    }    

    preg_match_all('#href=(?:([\"\'])([^\"\'>]\S*?)\1[^>]*|([^>\"\']+))>(.*?)</a>#is '$str$matches);
    foreach(
    $matches[2] as $key)
    {
    echo 
    $key; echo '<br>';
    }
    что то не получается связать это вместе..
     
    1 person likes this.
  8. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    #Wolf# По-хорошему, лучше сделать полный дамп базы и обработать, иначе будет слишком много запросов к БД.

    PHP:
    <?
    set_time_limit(0);
    $begin=0// С какой позиции начинать
    $count=10// Сколько строк БД обрабатывать за раз
    for($i=$begin;;$i+=$count)
    {
        
    $result=mysql_query("SELECT * FROM posts LIMIT $i,$count");
        if (!
    mysql_num_rows($result)) break;
        
        while (
    $row=mysql_fetch_array($result))
        {
            
    $tmp=preg_replace('~<a.*href="([^"]+)".*>.*</a>~Usi','$1',$row['full_news']);
            
    // В запросе на обновление не уверен насчет экранирования кавычек
            
    if ($tmp!=$row['full_news']) $update=mysql_query("UPDATE posts SET full_news='$tmp' WHERE full_news='".$row[full_news]."'");
        }
        @
    file_put_contents('cur_pos.txt',$i); // Пишем в файл текущую позицию, на всякий случай
    }

    Но повторюсь - лучше обрабатывать построчно дамп. Так можно будет проконтролировать, что все обработано правильно и не угробить случайно БД
     
    _________________________
    #8 Gifts, 17 Mar 2009
    Last edited: 17 Mar 2009
    2 people like this.
  9. draliokero

    draliokero Member

    Joined:
    14 Mar 2009
    Messages:
    83
    Likes Received:
    6
    Reputations:
    0
    Gifts, можете пример привести, с дампом как в php?
     
  10. Zedi

    Zedi Elder - Старейшина

    Joined:
    6 Jun 2007
    Messages:
    316
    Likes Received:
    120
    Reputations:
    13
    после $i=$begin у тебя две точки с запятой, чтот там намудрено, там должно быть три аргумента, типа for ($i = 0; $i < $p; $i++), в первом переменные стартовые, потом условие продолжения итераций цикла и 3: действие после каждой итерации(прохода)
     
  11. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    draliokero Разницы большой не будет - просто читаем файл дампа построчно (fgets), а потом просто восстанавливаем БД из этого дампа. Выгода - не убьем базу, меньшее количество обращений к БД, не надо следить за кавычками

    m0Hze Zedi Синтаксис for такой же как в Си. Любые переменные в for($i1;$i2;$i3) - могут быть пропущены. В случае пропуска второго параметра - цикл будет выполняться бесконечно. Поэтому внутри цикла есть break;

    #Wolf# В скрипт закралась ошибка, вместо $tmp=str_replace нужно $tmp=preg_replace
     
    _________________________
  12. #Wolf#

    #Wolf# Elder - Старейшина

    Joined:
    26 Mar 2008
    Messages:
    375
    Likes Received:
    166
    Reputations:
    16
    несколько вопросов:
    1)
    PHP:
    $i+=$count
    что это за += 0_0
    2) тестил с одной новостью. фор пока убрал. так новость отлично режется но не апдейтится. ругается .
    вот к примеру выборка из бд
    PHP:
    <div align="center"><img src="http://www.test.ru/posts/2008-02/1203842370_1203713115_73ed9d5d865d.jpg" style="border: none;" alt='Alcohol 120% 1.9.7.6221 + Activation Keymaker v3.6' title='Alcohol 120% 1.9.7.6221 + Activation Keymaker v3.6' /></div><br /><br /><b>Название:</bAlcohol 1201.9.7.6221 Activation Keymaker v3.6<br /><b>Разработчик:</b>
    <
    a href="http://rapidshare.com/files/94052968/alcohol_120__1.9.7.6221.rar" target="_blank">Скачать Download</a>
    и ругается на
    PHP:
    You have an error in your SQL syntaxcheck the manual that corresponds to your MySQL server version for the right syntax to use near 'Alcohol 120% 1.9.7.6221 + Activation Keymaker v3.6' title='Alcohol 120% 1.9.7.62' at line 1
    как я понимаю получается какая то херня с кавычками
     
    #12 #Wolf#, 19 Mar 2009
    Last edited: 19 Mar 2009
  13. flabber

    flabber New Member

    Joined:
    24 Jan 2007
    Messages:
    16
    Likes Received:
    4
    Reputations:
    0
    Аааа вы нарки... не легче сдампить это всё дело и пустить скрипт для распарсивания в шеле?...
     
  14. PaCo

    PaCo Elder - Старейшина

    Joined:
    6 Feb 2008
    Messages:
    436
    Likes Received:
    138
    Reputations:
    25
    2#Wolf#

    1)http://www.php.ru/manual/language.operators.assignment.html

    2)
    if ($tmp!=$row['full_news']) $update=mysql_query("UPDATE posts SET full_news='$tmp' WHERE full_news='".mysql_real_escape_string($row['full_news'])."'");
     
    1 person likes this.
  15. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    #Wolf# Ну я же написал что не уверен в экранировании) У PaCo тоже не совсем правильно. Надо:
    PHP:
    if ($tmp!=$row['full_news']) $update=mysql_query("UPDATE posts SET full_news='".mysql_real_escape_string($tmp).'\' WHERE full_news=\''.mysql_real_escape_string($row[full_news])."'"); 
     
    _________________________