def checkResultsLength(soup):
results_table_length = soup.find(id='body')
y = getattr(results_table_length, 'find_all', None)
if y is not None:
tr = results_table_length.find_all('tr')
return len(tr)
else:
return 0
На самом деле я сделал примерно также в конечном итоге. Однако в качестве разбираемой строки добавились html-теги с обеих сторон, которые стали удобными точками опорами. Попахивает, как вы написали, но работает. а это главное! :D
"Требовалось что-то около десяти инстансов PhantomJS"
Можете показать кусок кода (или направить на реализацию подобного решения), о котором вы говорите? Если я запускаю "тупо" 2 одинаковых скрипта (естественно на разный список ссылок), то я вижу, что первый работает нормально, а второй "плетется", иногда подтормаживая, или вообще останавливаясь. Не знаю точно в чем проблема: соединение, настройки удаленного сервера, или какие-то другие факторы.
"Нужно использовать wait()."
Расставил везде где нужно по time.sleep(1) или wait.until. Запинаний не было.
"Наличие/отсутствие попапов не играет роли. Все, что появляется в DOM, все можно отработать.". Это понятно, что все появляется в DOM. Сейчас в моем примере сервер отдает целый шаблон с html-тегами (а не просто массив данных), который при открытии появляется или наоборот удаляется. Все это ведь надо прокликать, так или иначе. Иначе как дать появится данным в дереве?
"Возможно. Но так ли это в вашем контексте ни кто кроме эксперимента не скажет."
В общем я сделал прокликивание ссылок через селениум, а парсинг данных через bs4. Работает, как и обещали - быстрее. В 2 с небольшим раза (т.е. не 5 часов, а 2.7 где-то). Это уже хорошо.
В общем, думаю, что ничего волшебного не бывает, т.к. все зависит от независящих от меня факторов: как быстро сервер отдает информацию, скорость канала и т.д. Единственное решение: максимально быстроработающий код и многопоточность. Насколько я понял. С первым я более-менее разобрался, а вот как увеличить ресурсы - пока нет. Парсинг происходит уже 2-й день.
Алексей Сундуков: спасибо за подробное пояснение (здесь и в ответе ниже). "реверс инжениринг по трудозатратам получается сильно дороже" мне пока вообще не понятно как это сделать в моем случае. Думаю вы правы.
"использование вместо headless браузера обычного SpiderMonkey (или V8)"
не понял, я должен использовать Mozilla, вместо Chrome в качестве драйвера?
Артем Кисленко
Данных нет в HTML, запросы 100% AJAX.
Попробовал PhantomJS - работает еще медленнее, чем Chrome.
Имитировать запросы нет возможности, я уже об этом писал.
Алексей Черемисин подскажите, как сделать на этапе создания файла with open(os.path.join(path, "output.cvs") название файла в виде foldername_output.csv?
"Так, вот, если задача поднять именно п. 2, то делать это можно и на selenium, просто придется запустить целый кластер из нод. " если запускать с десктопа, то какие ресурсы потребуются? И как лучше запустить в несколько потоков один скрипт?
Так уже и сделал, но спасибо за ответ, подтвердил что я сделал все правильно. Разве что принты у меня работают внутри цикла, чтобы записывать строку сразу при прохождении итерации.
def checkResultsLength(soup):
results_table_length = soup.find(id='body')
y = getattr(results_table_length, 'find_all', None)
if y is not None:
tr = results_table_length.find_all('tr')
return len(tr)
else:
return 0