Latest posts on Мультипоточность и мультипроцессинг при парсинге сайтов topichttp://python.su/forum/topic/36751/2019-02-14T23:40:10+02:00Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T23:40:10+02:00Rodegast199162> А почему не будет лучше, например разделить задачу между 4-мя ядрами по 15 тыс. ссылок из 60, а дальше уже запускать например в 1000 потоков каждый из 4-х процессов? <br/><br/>В этом есть смысл только если процессор испытывает значительную нагрузку, иначе multiprocessing будет только создавать проблемы.<br/>
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T22:52:14+02:00Room_on199161> И в чём проблема?<br/>Ни в чём, просто хотел убедиться, что твой способ подходит к моему случаю <img src="/static/djangobb_forum/img/smilies/smile.png" /> Спасибо.<br/><br/>Про конкурентость. А почему не будет лучше, например разделить задачу между 4-мя ядрами по 15 тыс. ссылок из 60, а дальше уже запускать например в 1000 потоков каждый из 4-х процессов? <br/><br/>
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T22:10:01+02:00Rodegast199158> Правильно ли я понимаю логику?<br/><br/>Нет. Есть 2 класса задач которые питонщики постоянно путают. Это конкурентность и параллелизм. Если кратко, то параллелизм это ускорение вычисления одной тяжёлой задали за счёт вычисления её частей одновременно на разных ядрах/процессорах, а конкурентность это предоставление доступа к одному ресурсу множеству клиентов.<br/>В python-е в приделах одного процесса можно реализовать только конкурентность, у тебя же конкурентная задача. Просто замени процессы на потоки и всё.<br/><br/>> Пишу в файл следующим образом, где proc - имя процесса<br/><br/>И в чём проблема?<br/><br/>> А одни и те же прокси, то срабатывают, то нет + иногда капчу на них выдает, которая со временем проходит.<br/><br/>Если прокси один раз не отвечает, то заноси его в “чёрный список” сроком например на 30 мин.
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T22:00:15+02:00Room_on199157<blockquote><em>JOHN_16</em><br/>ну самое просто сейчас, не пишите в файл. Соберите все данные в памяти, и только потом пишите в файл. “кривых” совсем не будет. У вас же проблема с конкурентным доступом.</blockquote>Подумал и понял, что пока не понимаю, как в памяти собрать данные из разных процессов. Сейчас если делаю глобальную переменную-счётчик кол-ва спарсенных страниц, то в каждом процессе свой подсчёт идёт, а не глобальный.
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T21:01:17+02:00Room_on199156<blockquote><em>JOHN_16</em><br/>ну самое просто сейчас, не пишите в файл. Соберите все данные в памяти, и только потом пишите в файл. “кривых” совсем не будет. У вас же проблема с конкурентным доступом.</blockquote><br/><blockquote><em>Rodegast</em><br/>Твоя основная ошибка в том что ты пытаешься решить конкурентную задачу при помощи многопоточности (да ещё и самым хреновым способом, хотя он единственный в случае Python-а). Для конкурентности используй модуль threading или асинхронность, тогда вопросы 2 и 3 сам собой отпадут.</blockquote>Первый вопрос был про быстродействие. Увеличивает ли её многопроцессорность по сравнению с многопоточностью. В моём понимании многопоточность позволяет хорошо ускорить задачи, в которых есть простой по времени, как в моём случае. То есть задача ждет ответа сервера до 5 секунд, потом берет следующий прокси. Пока одна задача ждет, то другой поток может запустить другую задачу и т.д. Но запустить 60 тыс. ссылок на страницы в 60 тыс. потоков наверное не самый правильный подход. И как я понял многопотоность ограничивается ресурсами одного ядра процессора. Многопроцессорность позволяет в свою очередь использовать все ресурсы. В связи с этим мне кажется, что нужно сделать несколько процессов, а в каждом из них несколько потоков. Правильно ли я понимаю логику?<br/><br/><blockquote><em>Rodegast</em><br/>Что мешает заранее удалить не работающие прокси?</blockquote>А одни и те же прокси, то срабатывают, то нет + иногда капчу на них выдает, которая со временем проходит. Поэтому поставил таймаут 5 секунд на ожидание ответа.<br/><br/><blockquote><em>Rodegast</em><br/>Вызывай перед закрытием файла:</blockquote><br/>Пишу в файл следующим образом, где proc - имя процесса<br/><div class="code"><pre> <span class="k">def</span> <span class="nf">write_csv</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">proc</span><span class="p">):</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'result '</span> <span class="o">+</span> <span class="n">proc</span> <span class="o">+</span> <span class="s1">'.csv'</span><span class="p">,</span> <span class="s1">'a+'</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">'utf-8'</span><span class="p">,</span> <span class="n">newline</span><span class="o">=</span><span class="s1">''</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">writer</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">writer</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">quotechar</span> <span class="o">=</span> <span class="s2">"'"</span><span class="p">,</span> <span class="n">delimiter</span><span class="o">=</span><span class="s1">','</span><span class="p">)</span>
<span class="n">writer</span><span class="o">.</span><span class="n">writerow</span><span class="p">((</span><span class="n">data</span><span class="p">[</span><span class="s1">'name'</span><span class="p">],</span>
<span class="n">data</span><span class="p">[</span><span class="s1">'id'</span><span class="p">]</span>
<span class="n">data</span><span class="p">[</span><span class="s1">'price'</span><span class="p">],</span>
<span class="n">data</span><span class="p">[</span><span class="s1">'url'</span><span class="p">],</span>
<span class="n">data</span><span class="p">[</span><span class="s1">'proxy'</span><span class="p">],</span>
<span class="n">data</span><span class="p">[</span><span class="s1">'proc'</span><span class="p">]))</span>
</pre></div><br/><br/>
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T20:26:58+02:00Rodegast199154> Multiprocessing использую с целью ускорения прохода по всем страницам<br/><br/>Твоя основная ошибка в том что ты пытаешься решить конкурентную задачу при помощи многопоточности (да ещё и самым хреновым способом, хотя он единственный в случае Python-а). Для конкурентности используй модуль threading или асинхронность, тогда вопросы 2 и 3 сам собой отпадут.<br/><br/>> 1 из 5 прокси срабатывает только<br/><br/>Что мешает заранее удалить не работающие прокси?<br/><br/>> Можно ли открыть одно соединение на все процессы/потоки и писать результаты в одну таблицу?<br/><br/>Да, так и нужно делать.<br/><br/>> Такое впечатление, что процессы конфликтуют между собой при записи в один и тот же файл. …. Стал писать для каждого процесса в свой файл (типа SpawnPoolWorker-1.csv), кривых строк стало гораздо меньше, но всё равно иногда встречаются.<br/><br/>Вызывай перед закрытием файла:<br/><div class="code"><pre> <span class="nb">file</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
<span class="n">os</span><span class="o">.</span><span class="n">fsync</span><span class="p">(</span><span class="nb">file</span><span class="p">)</span>
</pre></div>
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T17:40:23+02:00JOHN_16199149ну самое просто сейчас, не пишите в файл. Соберите все данные в памяти, и только потом пишите в файл. “кривых” совсем не будет. У вас же проблема с конкурентным доступом.
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T17:10:46+02:00Room_on199147<blockquote><em>JOHN_16</em><br/>в современном мире все больше такие задачи решаются асинхронным программированием.Писать все в 1 файл это конечно безумие.</blockquote>Стал писать для каждого процесса в свой файл (типа SpawnPoolWorker-1.csv), кривых строк стало гораздо меньше, но всё равно иногда встречаются.
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T17:08:49+02:00Room_on199146<blockquote><em>Rodegast</em><br/>> Какая ОС? С какой целью multiprocessing используется?</blockquote><br/>Запускаю локально на компе, Win10. Multiprocessing использую с целью ускорения прохода по всем страницам, т.к. в каждом потоке одна страница в среднем секунд 20 загружается (1 из 5 прокси срабатывает только).<br/>
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T14:59:14+02:00JOHN_16199144в современном мире все больше такие задачи решаются асинхронным программированием.<br/>Писать все в 1 файл это конечно безумие.
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T14:55:17+02:00Rodegast199142> Сейчас делаю всё в 100 потоков через мультипроцессинг….Имеет ли смысл использовать мультипоточность? Или может быть стоит сделать мультипоточность внутри мультипроцессинга?<br/><br/>Какая ОС? С какой целью multiprocessing используется?<br/>
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T14:02:56+02:00PEHDOM199140<blockquote><em>Room_on</em><br/>Сейчас делаю всё в 100 потоков через мультипроцессинг. Занимает около 4 Гб оперативной памяти.<br/>Имеет ли смысл использовать мультипоточность? Или может быть стоит сделать мультипоточность внутри мультипроцессинга? Есть ли разница?</blockquote>это тема для целого холовара… в каждом конкретном случае будет свой ответ. можете почитать <a href="https://stackoverflow.com/questions/3044580/multiprocessing-vs-threading-python">https://stackoverflow.com/questions/3044580/multiprocessing-vs-threading-python</a> и решить что в вашем случае подходит больше.<br/><blockquote><em>Room_on</em><br/>Вопрос 2.<br/>При записи в CSV часть строк получаются кривые, попадает только часть фразы из поля. Такое впечатление, что процессы конфликтуют между собой при записи в один и тот же файл. Может ли действительно быть такое и ка</blockquote>шо серьезно? у вас все 100 процессов одновеременно пишут в один файл? данунах. <br/>НО не думаю что у вас кривые строки именно изза этого(хотя конечно все может быть). Честно говоря я сомневаюсь что вы можете одновременно открыть файл на запись из нескольких процессов.<br/>Но все же: <br/>1 существуют блокираторы(Lock) для подобных случаев.<br/>2. если у вас 100 процессов, ИМХО лучше завести отдельный процесс который будет брать данные из очереди(Queue в самом простом случае) и писать данные в файл, а остальные процессы будут вместо записи в файл кидать данные в очередь.<br/><blockquote><em>Room_on</em><br/>Как сделать так, чтобы разные процессы обменивались между собой переменными? </blockquote>гуглите Value Array и Manager<br/><a href="https://docs.python.org/3.4/library/multiprocessing.html#sharing-state-between-processes">https://docs.python.org/3.4/library/multiprocessing.html#sharing-state-between-processes</a><br/><br/><blockquote><em>Room_on</em><br/>Вопрос 4.<br/>Как правильно писать результаты в БД? Если делать в лоб, то могу после парсинга каждой страницы открывать соединение, запускать нужный курсор, делать комит и закрывать соединение. Но наверное это не очень оптимально. Можно ли открыть одно соединение на все процессы/потоки и писать результаты в одну таблицу?<br/></blockquote>ровно так же как и в вопросе 2, создаете отдельный процесс, котроый берет данные из очереди и пишет в БД, остальные процессы эти данные помешают в очередь.<br/><br/>
Общий :: Python для новичков :: Мультипоточность и мультипроцессинг при парсинге сайтов
2019-02-14T12:16:58+02:00Room_on199134Всем добрый день. Пишу парсер сайта, который должен обходить 60 тыс. страниц с карточками товара и собирать с них нужные атрибуты. Использую список из 16 тыс. прокси и 1 тыс. юзер-агентов, из которых выбираю сочетание случайным образом. Если ответа нет в течение 5 секунд, то беру следующий прокси. В среднем 1 из 5 раз удается получить страницу. Основное время, как я понимаю, уходит на ожидание ответа страницы. Результаты пишу в CSV.<br/><br/>Вопрос 1.<br/>Сейчас делаю всё в 100 потоков через мультипроцессинг. Занимает около 4 Гб оперативной памяти. <br/>Имеет ли смысл использовать мультипоточность? Или может быть стоит сделать мультипоточность внутри мультипроцессинга? Есть ли разница?<br/><br/>Вопрос 2.<br/>При записи в CSV часть строк получаются кривые, попадает только часть фразы из поля. Такое впечатление, что процессы конфликтуют между собой при записи в один и тот же файл. Может ли действительно быть такое и как это исправить?<br/><br/>Вопрос 3.<br/>Как сделать так, чтобы разные процессы обменивались между собой переменными? Например, сделать единый счетчик кол-во обработанных страниц, т.е. чтобы разные процессы увеличивали переменную на +1. Сейчас получается, что в каждом процессе своя переменная (делаю через Global).<br/><br/>Вопрос 4.<br/>Как правильно писать результаты в БД? Если делать в лоб, то могу после парсинга каждой страницы открывать соединение, запускать нужный курсор, делать комит и закрывать соединение. Но наверное это не очень оптимально. Можно ли открыть одно соединение на все процессы/потоки и писать результаты в одну таблицу?<br/><br/>Заранее спасибо за ответы и советы.<br/><br/>