Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   PHP, PERL, MySQL, JavaScript (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   [Q]Парсинг большой бд (https://forum.antichat.xyz/showthread.php?t=111393)

#Wolf# 16.03.2009 12:56

[Q]Парсинг большой бд
 
Что имеем:
1) большую бд (порядка) 300 метров
2) 63к записей.

Значит в каждой записи имеется несколько ссылок
Цитата:

Текст текст текст текст текст
<a href="http://rapidshare.com/download.rar.html" target="_blank">Cкачать </a>
текст текст текст текст текст
<a href="http://rapidshare.com/download2.rar.html" target="_blank">Cкачать </a>
В целях сео оптимизации хотелось бы превратить кликабельные ссылки в простой текст
Цитата:

<a href="http://rapidshare.com/download.rar.html" target="_blank">Cкачать </a>
-->
Цитата:

http://rapidshare.com/download.rar.html
как бы с небольшими юд это будет достаточно просто сделать, но .... это не мой случай.
Хотел бы выслушать ваши предложения

ph1l1ster 16.03.2009 13:16

можно и так:

Код:

#!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);

и больше размеры парсил

Gray_Wolf 16.03.2009 13:17

Цитата:

1) большую бд (порядка) 300 метров
2) 63к записей.
Парсили 2 милиона записей и всё в порядке :)

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

rcc0023 16.03.2009 13:48

Вполне можно и на php с использованием sleep(1)

-=Static=- 16.03.2009 13:52

set_time_limit(0)
SET TRANSATION
и поехал че хочешь с ней ковырять...заливай на удаленную машину, запускай и иди курить, придешь - соптимизируется... У нас на работе для 2-3кк записей на ночь оставляли

#Wolf# 16.03.2009 14:04

ах да..кто не понял база - мускул
UPD// набросать кто может на php?

#Wolf# 17.03.2009 07:28

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>';


что то не получается связать это вместе..

Gifts 17.03.2009 09:22

#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); // Пишем в файл текущую позицию, на всякий случай
}

Но повторюсь - лучше обрабатывать построчно дамп. Так можно будет проконтролировать, что все обработано правильно и не угробить случайно БД

m0Hze 17.03.2009 14:02

for($i=$begin;;$i+=$count) - ошибко, или я чтото не понимаю оО

draliokero 17.03.2009 14:09

Gifts, можете пример привести, с дампом как в php?

Zedi 17.03.2009 17:16

Цитата:

Сообщение от m0Hze
for($i=$begin;;$i+=$count) - ошибко, или я чтото не понимаю оО

после $i=$begin у тебя две точки с запятой, чтот там намудрено, там должно быть три аргумента, типа for ($i = 0; $i < $p; $i++), в первом переменные стартовые, потом условие продолжения итераций цикла и 3: действие после каждой итерации(прохода)

Gifts 18.03.2009 00:29

draliokero Разницы большой не будет - просто читаем файл дампа построчно (fgets), а потом просто восстанавливаем БД из этого дампа. Выгода - не убьем базу, меньшее количество обращений к БД, не надо следить за кавычками

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

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

#Wolf# 19.03.2009 04:46

Цитата:

Сообщение от Gifts
#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); // Пишем в файл текущую позицию, на всякий случай
}

Но повторюсь - лучше обрабатывать построчно дамп. Так можно будет проконтролировать, что все обработано правильно и не угробить случайно БД

несколько вопросов:
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 

как я понимаю получается какая то херня с кавычками

flabber 19.03.2009 05:06

Аааа вы нарки... не легче сдампить это всё дело и пустить скрипт для распарсивания в шеле?...

PaCo 19.03.2009 05:08

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'])."'");

Gifts 19.03.2009 12:52

#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])."'"); 



Время: 04:32