ползать соскоб и нить? с php - PullRequest
1 голос
/ 08 июня 2009

У меня есть персональный веб-сайт, который сканирует и собирает MP3 из моих любимых музыкальных блогов для последующего прослушивания ...

Как это работает, задание CRON запускает скрипт .php раз в минуту, который сканирует следующий блог в БД. Результаты помещаются в БД, а затем второй скрипт .php сканирует собранные ссылки.

Скрипты проскальзывают на два уровня вниз по странице, так что .. главная страница www.url.com и ссылки на этой странице www.url.com/post1 www.url.com/post2

Моя проблема в том, что я начинаю получать большую коллекцию блогов. Они сканируются только раз в 20-30 минут, и когда я добавляю новый блог в сценарий, создается резервная копия при сканировании ссылок, поскольку обрабатывается только одна из них каждую минуту.

Из-за того, как работает PHP, кажется, я не могу просто позволить сценариям обрабатывать более одной или ограниченное количество ссылок из-за времени выполнения сценария. Ограничения памяти. Тайм-ауты и т. Д.

Также я не могу запустить несколько экземпляров одного и того же скрипта, поскольку они будут перезаписывать друг друга в БД.

Как лучше всего ускорить этот процесс.

Есть ли способ, которым я могу иметь несколько сценариев, влияющих на БД, но писать их так, чтобы они не перезаписывали друг друга, а ставили в очередь результаты?

Есть ли какой-нибудь способ создать многопоточность в PHP, чтобы скрипт мог обрабатывать ссылки в своем собственном темпе?

Есть идеи?

Спасибо.

Ответы [ 5 ]

2 голосов
/ 08 июня 2009

ИСПОЛЬЗОВАТЬ CURL MULTI!

Curl-mutli позволит вам обрабатывать страницы параллельно.

http://us3.php.net/curl

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

Вы создаете список блогов, которые хотите почистить, отправляете их на curl multi. Подождите, а затем последовательно обработайте результаты всех вызовов. Затем вы можете сделать второй проход на следующем уровне вниз

http://www.developertutorials.com/blog/php/parallel-web-scraping-in-php-curl-multi-functions-375/

2 голосов
/ 08 июня 2009

псевдокод для запуска параллельных сканеров:

start_a_scan(){
    //Start mysql transaction (needs InnoDB afaik)        
    BEGIN 
        //Get first entry that has timed out and is not being scanned by someone
        //(And acquire an exclusive lock on affected rows)
        $row = SELECT * FROM scan_targets WHERE being_scanned = false AND \
                (scanned_at + 60) < (NOW()+0) ORDER BY scanned_at ASC \
                      LIMIT 1 FOR UPDATE
        //let everyone know we're scanning this one, so they'll keep out
        UPDATE scan_targets SET being_scanned = true WHERE id = $row['id']
    //Commit transaction
    COMMIT
    //scan
    scan_target($row['url'])
    //update entry state to allow it to be scanned in the future again
    UPDATE scan_targets SET being_scanned = false, \
              scanned_at = NOW() WHERE id = $row['id']
}

Вам, вероятно, понадобится «очиститель», который периодически проверяет наличие каких-либо прерванных сканов и сбрасывает их состояние, чтобы их можно было сканировать снова.

И тогда у вас может быть несколько процессов сканирования, работающих параллельно! Yey!

ура!

РЕДАКТИРОВАТЬ : Я забыл, что вам нужно сделать первый SELECT с помощью FOR UPDATE. Подробнее здесь

1 голос
/ 08 июня 2009

Это, конечно, не ответ на ваш вопрос, но если вы хотите изучать python, я рекомендую вам взглянуть на Scrapy, фреймворк с открытым исходным кодом для сканирования и сканирования , который должен удовлетворить ваши потребности. Опять же, это не PHP, а Python. Это, как всегда, очень распространяемый и т. Д. Я использую его сам.

1 голос
/ 08 июня 2009

Из-за того, как работает PHP, кажется, я не могу просто позволить скриптам обрабатывать более одной или ограниченное количество ссылок из-за времени выполнения скрипта. Ограничения памяти. Тайм-ауты и т. Д.

Ограничение памяти - только проблема, если ваш код утечек памяти. Вы должны это исправить, а не поднимать лимит памяти. Время выполнения скрипта - это мера безопасности, которую вы можете просто отключить для своих cli-скриптов.

Также я не могу запустить несколько экземпляров одного и того же скрипта, так как они будут перезаписывать друг друга в БД.

Вы можете сконструировать свое приложение таким образом, чтобы экземпляры не перекрывали друг друга. Типичный способ сделать это было бы разделить на сайт; Например. Запустите отдельный скрипт для каждого сайта, который вы хотите сканировать.

0 голосов
/ 08 июня 2009

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

должно быть в состоянии изменить ваш код, чтобы вы могли запускать несколько экземпляров одновременно - вам придется опубликовать сценарий, чтобы кто-нибудь мог посоветовать дальше. Как говорит Питер, вам, вероятно, нужно взглянуть на дизайн. Предоставление кода в пастбине поможет нам помочь вам:)

...