Wpis z mikrobloga

Mam do zrobienia niby trywialny scrapping stron. Musi to działać możliwie szybko, nie mogę korzystać z zewnętrznych serwisów. Mój stack jest oparty o #php
W tym momencie wykorzystuję kolejkowanie z wieloma consumerami, do każdego message'a wrzucam pojedynczy url, pobieram i scrappuję ją. Myślałem o zastosowaniu curlmultiinit i wrzucanie jako messega contentu strony, ale raz, nie wiem czy multi curl coś przyśpieszy, a dwa, czy tak duże messege nie będą problemem.
Myślałem też o użyciu wielowątkowości, ale nie wiem czy przyśpieszy to względem multiprocessingu (tzn. wielu consumerów).

Jakie inne dobre praktyki mogę zastosować przy tym projekcie? Inb4, nie zmienię języka.
#programowanie
  • 11
@Jurix: swoole ( ͡° ͜ʖ ͡°) przy tym podejściu niestety będziesz zależy właśnie od masy consumerów,

możesz rozbić to na jeszcze dwa oddzielne message - jeden jako zaciągnięcie contentu strony i tutaj przetwarzać kilka urli jednocześnie na jednej wiadomości i zaciągać dane async way(po prostu guzzle async, a właśnie tutaj najlepiej by się swoole sprawdził), i puszczać drugi message wtedy gdy będzie content strony i url -
@Jurix: Taktyk.

Ciekaw jestem odpowiedzi, ale swoją drogą, korzystając tylko z PHP to przeszedłbym do problemu podobnie, tzn. korzystałbym z dobrodziejstw np. Symfony Messenger i do tego jakiś porządny transport np. Redis, chociaż sam Doctrine wydaje się, że to "pociągnie'.

Ponadto każda czynność i zdarzenie na osobny Message\Event, wg. specyfikacji tego komponentu od Symfony.

Wtedy jak masz 1000 URL, to każdy trafia do osobnego zadania, które wykonywane są asynchronicznie. I wszystko
@Jurigag: Co mi da swoole czego nie daje mi rabbit? W obu elementach mam osobne procesy, jedynie że w swoole korzysta z istniejącego procesu zamiast tworzyć nowy? Chociaż w symfony też mam długo żyjący proces php'a.

Właśnie myślałem o takim rozbiciu jak opisałeś, ale czy tak duże message (cały content strony ok. 500kb każdy), razy tysiące message nie będzie problemem, rabbit na słabym serwerze nie będzie się dławić?
@Jurigag: Chodzi mi o sposób "przechowywania" tych asynchronicznych zadań do wykonania, Symfony ma domyślnie Doctrine i do mniejszych zadań się moim zdaniem sprawdza, choć lepsze są inne rozwiązania. Doctrine, wiadomo dodatkowy narzut.

@Jurix: Kiedyś robiłem coś podobnego jak szukałem mieszkania na ogłoszeniach typu Gumtree, pokrótce wyglądało to tak.

1. Pierwszy skrypt - wywoływany, co kilka minut min przez systemowy cron, ma za zadanie zebrać wszystkie widoczne url ogłoszeń, wypluwa dajmy
@Jurix: swoole da ci zielone wątki - chociażby to że mógłbyś już przetwarzać daną stronę w zielonym wątku gdy masz zablokowany I/O gdy idzie request http albo gdy idzie zapis tych danych po ich przetworzeniu itp
@Jurix: może i zapewniają tylko wtedy musisz mieć ich dużo więcej - rodzi to dodatkowe koszta, jak masz nieograniczone no to spoko, ale wtedy można równie dobrze lambd użyć, a duże strony po prostu wrzucać na s3
@Jurix: no i tak jak mirek wyżej wspominał, przy scrappingu stron trzeba pamiętać o jakimś proxy, bo po prostu cię zbanują łatwo, ja swego czasu korzystałem ze https://smartproxy.com residental proxies w jednym projekcie aby instagrama scrappować, nawet się to sprawdzało

większość ogarniętych stron jak zobaczy spam requestami z IP z data center zablokuje cię już po kilku-kilkunastu sekundach, np instagram, wystarczy zrobić jakieś 100 zapytań na minutę i już proszą cię
@Jurigag: jak miałem pewną ważną sprawę, a nie potrafiłem ominąć tych wszystkich blokad i captchy, to kombinowałem tak, że używałem do tego lokalnie swojego komputera, internet z UPC i ewentualna zmiana IP po zresetowaniu routera, korzystałem z webdriverów zamiast z curl, workery odpalały mi ręcznie przeglądarkę, a jak się pojawiła captcha to ręcznie ją rozwiązywałem i był spokój na cały dzień, ale tych żądań było stosunkowo mało