Я создал сканер, который должен был работать примерно на 5 млн. Страниц (путем увеличения идентификатора URL), а затем анализирует страницы, содержащие информацию, которая мне нужна.
после использования алгоритма, который работает наURL-адреса (200 КБ) и сохраненные хорошие и плохие результаты, которые я обнаружил, что я трачу много времени.Я мог видеть, что есть несколько возвращаемых вычитаемых, которые я могу использовать, чтобы проверить следующий действительный URL.
вы можете увидеть вычитаемые довольно быстро (немного ex 'из нескольких первых "хороших идентификаторов") -
510000011 # +8
510000029 # +18
510000037 # +8
510000045 # +8
510000052 # +7
510000060 # +8
510000078 # +18
510000086 # +8
510000094 # +8
510000102 # +8
510000110 # etc'
510000128
510000136
510000144
510000151
510000169
510000177
510000185
510000193
510000201
после сканирования около 200 тыс. URL, которые дали мне только 14 тыс. Хороших результатов, я знал, что теряю время и нуждаюсь в оптимизации, поэтому я запустил некоторую статистику и создал функцию, которая будет проверять URL при увеличенииидентификатор с 8 \ 18 \ 17 \ 8 (верхние возвращаемые вычитаемые значения) и т. д. '
это функция -
def checkNextID(ID):
global numOfRuns, curRes, lastResult
while ID < lastResult:
try:
numOfRuns += 1
if numOfRuns % 10 == 0:
time.sleep(3) # sleep every 10 iterations
if isValid(ID + 8):
parseHTML(curRes)
checkNextID(ID + 8)
return 0
if isValid(ID + 18):
parseHTML(curRes)
checkNextID(ID + 18)
return 0
if isValid(ID + 7):
parseHTML(curRes)
checkNextID(ID + 7)
return 0
if isValid(ID + 17):
parseHTML(curRes)
checkNextID(ID + 17)
return 0
if isValid(ID+6):
parseHTML(curRes)
checkNextID(ID + 6)
return 0
if isValid(ID + 16):
parseHTML(curRes)
checkNextID(ID + 16)
return 0
else:
checkNextID(ID + 1)
return 0
except Exception, e:
print "somethin went wrong: " + str(e)
в основном это то, что -checkNextID (ID) получаетпервый идентификатор, который я знаю, который содержит данные минус 8, поэтому первая итерация будет соответствовать первому предложению «if isValid» (isValid (ID + 8) вернет True).
lastResult являетсяпеременная, которая сохраняет последний известный идентификатор URL, поэтому мы будем работать до тех пор, пока numOfRuns не будет
isValid () - это функция, которая получает идентификатор + одно из вычитаемых значений и возвращает True, если URL-адрессодержит то, что мне нужно и сСохраняет объект супруга URL-адреса в глобальную переменную с именем - ' curRes ', он возвращает False, если URL-адрес не содержит данных, которые мне нужны.
parseHTML - это функция, которая получает объект супа (curRes), анализирует нужные мне данные и затем сохраняет данные в CSV, а затем возвращает True.
если isValid () возвращает True, мы вызовем parseHTML (), а затем попробуйте проверить следующий идентификатор + вычитаемые (вызывая checkNextID (идентификатор + вычитаемые), если ни один из них не вернет то, что я ищу, я увеличу его на 1 и проверю снова, пока не найдуследующий действительный URL.
вы можете увидеть остальную часть кода здесь
после выполнения кода я получил около 950 ~ хороших результатов, и внезапно возникло исключение -
"что-то пошло не так: максимальная глубина рекурсии превышена при вызове объекта Python"
Я видел на WireShark, что сценарий застрял на id - 510009541 (я запустил свой скриптс 510000003), скрипт пытался получить тон URL с этим идентификатором несколько раз, прежде чем я заметил ошибку и остановил ее.
Мне было очень приятно видеть, что я получаю те же результаты, но в 25–40 раз быстрее, чем мой старый скрипт, с меньшим количеством HTTP-запросов., это очень точно, я пропустил только 1 результат на 1000 хороших результатов, который я нашел, 5 миллионов раз невозможно найти, мой старый скрипт работал 30 часов и получил 14-15K результатов, когда мой новый скрипт дал мне960 ~ результаты за 5-10 минут.
Я читал об ограничениях стека, но должно быть решение для алгоритма, который я пытаюсь реализовать в Python (я не могу вернуться к своему старому "алгоритм" , он никогда не закончится).
Спасибо!