@ohhheexx нужно на отправлять на сервер параметр, что каптча регистро зависимая.
LOCK в многопотоке
-
@senerg said in LOCK в многопотоке:
@fox , @Denis_krsk , @xclsv
Например, в нескольких потоках делаю гет запрос, пересчитываю количество ссылок, которые есть в ответе, увеличиваю глобальную переменную на это количество.То, для чего Вы пытаетесь придумать велосипед, делается иначе. Сначала в однопотоке пересчитывается количество ссылок. Затем в многопотоке эти ссылки обрабатываются.
@senerg said in LOCK в многопотоке:
Я два дня читал про многопоточность в басе, пока не понял, что ее просто нет. Вместо нее есть возможность запускать несколько экземляров одной и той же функции в несколько потоков с возможностью чтения общих данных каждым потоком. И все. По факту многопоточности нет. Нельзя взять данные из одного потока, обработать в другом и вернуть обратно.
Многопоточность есть. Просто она работает не так, как Вы себе это представляете. При этом Вы не ещё даже не пытались подумать, с какими проблемами столкнётесь, если она будет работать именно так, как Вам нужно.
Проблем не в бас и его функционале, а в том, что Вы не придумали алгоритм и не предусмотрели обработку ошибок, которые будут возникать при его реализации. -
@xclsv said in LOCK в многопотоке:
Проблем не в бас и его функционале, а в том, что Вы не придумали алгоритм и не предусмотрели обработку ошибок, которые будут возникать при его реализации.
Полностью согласен. Я же не говорю, что бас вдруг стал плохим, просто при придумывании алгоритма нужно учитывать возможности и особенности бас при чем не только в многопотоке и формировать алгоритм под бас, а не придуманный алгоритм брать и натягивать на бас. Самое большое неудобство заключается в том, что нет мануала, где было бы написано, что можно а что работать не будет.
@denis_krsk said in LOCK в многопотоке:
Если в скрипте есть асинхронные действия это нормально, я говорил только о том, что бы между чтением и записью глоб переменной их не было
Значит если функция, запущенная в многопотоке, сначала делает какие-то асинхронные действия, затем читает глобальную переменную, обрабаывает ее только синхронными действиями, а затем записывает полученное значение в эту же глобальную переменную, то проблем не будет не зависимо от колчества запущенных потоков?
-
Если в скрипте есть асинхронные действия это нормально, я говорил только о том, что бы между чтением и записью глоб переменной их не было
Значит если функция, запущенная в многопотоке, сначала делает какие-то асинхронные действия, затем читает глобальную переменную, обрабаывает ее только синхронными действиями, а затем записывает полученное значение в эту же глобальную переменную, то проблем не будет не зависимо от колчества запущенных потоков?
Да!
Полностью согласен. Я же не говорю, что бас вдруг стал плохим, просто при придумывании алгоритма нужно учитывать возможности и особенности бас при чем не только в многопотоке и формировать алгоритм под бас, а не придуманный алгоритм брать и натягивать на бас. Самое большое неудобство заключается в том, что нет мануала, где было бы написано, что можно а что работать не будет.
Ну в любом языке есть свои особенности которые учитываются. А если чего-то нет или непонятно из мануала, то это легко узнается с помощью тестов.
-
@xclsv , она есть, но с ограничениями. Вы не можете создавать новый поток когда вам вздумается. Вы не можете запустить в многопотоке функцию, в которой между чтением и записью в глобальную переменную есть асинхронное действие. И еще наверняка много других ограничений, о которых я пока не знаю. Есть так как есть, и огромная благодарность автору баса за то, что есть хоть так. Даже в текущем воложении этого более чем достаточно для 90% задач.
Я лишь говорю о том, что нет мануала о том что можно, что нет. И пока сам носом не натыкаешься на все эти особенности о них и не узнаешь. -
@senerg said in LOCK в многопотоке:
Вы не можете создавать новый поток когда вам вздумается
Да, действия new Thread() в BAS'e из коробки пока нет.
Вы не можете запустить в многопотоке функцию, в которой между чтением и записью в глобальную переменную есть асинхронное действие.
Почему? Всегда пользовался именно таким алгоритмом. Вам уже много раз говорили, запись в глобальную переменную работает правильно и логично. Выкиньте слово асинхронные действия из своего лексикона, пока не поймёте что это такое (без обид).
Представьте ведро

В него не глядя накладывают раствор 5 строителей, если строитель будет смотреть в ведро сразу как положил в него раствор, он будет всегда знать, сколько его сейчас в ведре.Так и с глобальной переменной, увеличить или записать новые данные в глобальную переменную можно без ограничений, но у вас может получиться неправильная логика, если проверять раствор в ведре не сразу.
-
@senerg said in LOCK в многопотоке:
@xclsv , она есть, но с ограничениями. Вы не можете создавать новый поток когда вам вздумается. Вы не можете запустить в многопотоке функцию, в которой между чтением и записью в глобальную переменную есть асинхронное действие. И еще наверняка много других ограничений, о которых я пока не знаю. Есть так как есть, и огромная благодарность автору баса за то, что есть хоть так. Даже в текущем воложении этого более чем достаточно для 90% задач.
Я лишь говорю о том, что нет мануала о том что можно, что нет. И пока сам носом не натыкаешься на все эти особенности о них и не узнаешь.Я так понял, Вы решаете задачу парсинга неизвестного количества страниц. Что мешает посчитать их количество и потом распределить в многопотоке? Не нужно будет пользоваться глобальными переменными. Не нужно будет заморачиваться с добавлением потока и асинхронными действиями. К тому же это намного эффективнее и по времени и по ресурсам. Уже предлагал это в соседней теме, может не увидели.
-
@fox Я не знаю что вы понимаете под словом "асинхронные", но я понимаю вот это, а не ведро.
@xclsv said in LOCK в многопотоке:
Вы решаете задачу парсинга неизвестного количества страниц. Что мешает посчитать их количество и потом распределить в многопотоке?
Чтобы узнать количество нужно сделать запрос на страницу и в ответе посмотреть пришла ли нужная страница (или есть ли кнопка перехода на следующую страницу). Т.е. придется либо все 100 запросов делать по очереди в одном потоке, либо отправить по одному запросу в 100 потоков, какие из них правильные данные не получат, значит их нет. Но тогда всегда будут лишние запросы к несуществующим страницам.
-
@senerg said in LOCK в многопотоке:
Чтобы узнать количество нужно сделать запрос на страницу и в ответе посмотреть пришла ли нужная страница (или есть ли кнопка перехода на следующую страницу)
Совсем не обязательно.
Вы можете делать запрос не к каждой странице, а, к примеру, через каждые 100 страниц. Затем уменьшать интервал вдвое каждый раз, когда ответа не будет и откатываться назад. Этот метод называется "делением отрезка пополам". Он откровенно неэффективен лишь когда у вас будет 1 страница.
Кстати, иногда на пустые страницы серверы отдают ответ 404. Это означает, что не обязательно смотреть и парсить весь ответ. Достаточно проверить статус ответа.
Почти все пагинаторы на сайтах написаны по какому-то алгоритму. Вы можете спарсить с первой страницы количество товаров. Зная число товаров на одной странице можно вычислить число страниц.
У меня была ситуация, когда пагинатора не было и никак нельзя было спарсить число страниц. Вычислять по каким-то причинам тоже было невозможно. Пришлось применить военную хитрость. Я просто парсил страницы подряд, проверяя, есть ли на них данные. Если нет, поток фейлился с запретом перезапуска. Профит. В этом случае, чисто лишних запросов будет равно числу потоков. Вероятно, они будут содержать пустые ответы. Не вижу проблемы в их наличии. Обойти это можно через Прервать скрипт без галочки Мгновенное завершение. Но это не очень удобно, ибо скрипт завершится полностью, хоть и подождёт завершения каждого потока. Полагаю, функцию, вызванную в многопотоке так остановить не получится.
Но и это не всегда работает. Вообще, нужно смотреть конкретную ситуацию. Скиньте ссылку, откуда надо спарсить число страниц. Попробуем определить оптимальный алгоритм. -
@xclsv said in LOCK в многопотоке:
Зная число товаров на одной странице можно вычислить число страниц
Не выйдет. На некоторых страницах али вставляет рекламный товар в списке выдачи. На одной странице 48 товаров, а может быть 47 если рекламный товар будет на странице.
Я делаю парсер для любой страницы выдачи али. Пока план такой: запускать 100 торов по одному для каждого потока, затем в одном потоке загружать первую страницу, получать с нее 48 урлов на товары и, получив ссылку на вторую страницу, составить список ссылок на все 100 страниц выдачи. Затем запустить в 100 потоках парсинг каждой страницы (3 гет запроса в трех потоках на товар), с выводом данных в глобальный список с индексом 1+48*page_index, после удалить из него пустые строчки, которые появятся из-за возможного появления рекламного товара на странице.
Не знаю только на сколько али понравится около 1000 запросов в секунду, есть у вас опыт с парсерами? -
@xclsv said in LOCK в многопотоке:
Делаете один запрос к странице №100500. Автоматически попадёте на последнюю, откуда и спарсите количество страниц рубрики.
С чего вы это взяли?
Вот вторая страница
Вот 100500
Вы про скорость парсинга не знаете? Думаю 1000 в секунду не стоит, а то обвинят в ддос атаке) -
@senerg said in LOCK в многопотоке:
С чего вы это взяли?
Вот вторая страница
Вот 100500С того что снифал запрос не с параметром страницы браузера, а запрос к странице через "перейти к странице" в правом нижнем углу экрана.

В ответ сервер али редиректит на последнюю или на 100 страницу(смотря что меньше).@senerg said in LOCK в многопотоке:
Вы про скорость парсинга не знаете? Думаю 1000 в секунду не стоит, а то обвинят в ддос атаке)
Али выдержит и 1кк запросов в секунду без проблем. Если будет блок по ip - добавьте прокси.
А вообще, беспокойство за бан чуток противоречит политике разработки многопоточных скриптов =) -
@xclsv said in LOCK в многопотоке:
Али выдержит и 1кк запросов в секунду без проблем. Если будет блок по ip - добавьте прокси.
А вообще, беспокойство за бан чуток противоречит политике разработки многопоточных скриптов =)Нет, не противоречит, просто интересуюсь как на практике дела. Думаю, что качать с них 100 мегабит будет палевно, даже если прокси постоянно менять. Хочу какой-то средний вариант подобрать, чтобы по нагрузке для них было не заметно.
-
@xclsv said in LOCK в многопотоке:
В ответ сервер али редиректит на последнюю или на 100 страницу(смотря что меньше).
Во время редиректа с введенной страницей номер 999 проходит вот такой запрос:
https://gj.mmstat.com/ae.pc_click.statweb_ae_click?gmkey=&gokey=ae_project_id%3D15218%26ae_page_type%3Dlist%26ae_page_area%3Dlist%26ae_button_type%3Dpage_go%26ae_object_type%3Dpage_num%26ae_object_value%3D999%26ae_ismember%3Dfalse%26ae_user_id%3D11.139.3.106.1542308148948.206313.4%26ae_click_behavior%3Dleft%26st_page_id%3Dn690ff97kt0cau3e16718bffe4721b6af70910a2df%26ali_apache_track%3D-%26jsver%3Daplus_std%26lver%3D8.7.2%26pver%3D0.4.10%26cache%3Dc3d53e6%26_slog%3D0&cna=N690FF97kT0CAU3eZX8xNubH&spm-cnt=2114.search0104.0.0.4deb3eadGK29lt&logtype=2А после него уже как-то высчитывает, что страниц в данном случае всего две и отправляет второй запрос сюда:
https://www.aliexpress.com/wholesale?isrefine=y&site=glo&g=y&SortType=total_tranpro_desc&SearchText=dress&page=2&CatId=200003482&initiative_id=SB_20181115110022&needQuery=n&pvId=10-100019007,5-100014064,14-173,200000329-200001248,200000446-200001484,100004669-100006419Честно говоря, у меня пока не достаточно знаний чтобы его повторить.
-
@senerg said in LOCK в многопотоке:
Честно говоря, у меня пока не достаточно знаний чтобы его повторить
Его нет необходимости повторять
Выполните запрос к 999 странице и оставьте галочку "следовать переадресациям". В ответ должен прийти код последней страницы. -
@xclsv said in LOCK в многопотоке:
Выполните запрос к 999 странице и оставьте галочку "следовать переадресациям"
Показывает несуществующую страницу.
https://www.aliexpress.com/wholesale?isrefine=y&site=glo&g=y&SortType=total_tranpro_desc&SearchText=dress&page=999&CatId=200003482&initiative_id=SB_20181115110022&needQuery=n&pvId=10-100019007,5-100014064,14-173,200000329-200001248,200000446-200001484,100004669-100006419