I. Introdução
Depois de muitas vezes nós escrevemos um réptil, para atingir os requisitos vai encontrar muita coisa para melhorar o lugar, que é muito importante ponto está rastejando velocidade. Este artigo explica como usar o código através do multi-processo, multi-thread, co-rotina para melhorar a velocidade rastreamento. Nota: Nós não insights sobre a teoria e princípio, tudo em seu código.
Em segundo lugar, síncrona
Primeiro, nós escrever uma répteis simplificados, cada segmento funcional, conduta consciente programação funcional. O código seguinte é um objecto 300 Baidu página de acesso e devolver um código de estado, em que a função pode ser ciclos parse_1 conjunto, cada ciclo do número actual ciclo (a partir de 0) e a função de entrada URL parse_2.
solicitações de importação
parse_1 def ():
url = 'https://www.baidu.com'
para i na gama (300):
parse_2 (url)
def parse_2 (url):
= resposta requests.get (URL)
print (response.status_code)
se __name__ == '__main__':
parse_1 ()
Desempenho é consumido principalmente na solicitação IO, quando a URL de solicitação usando o modo single-threaded conduzirá inevitavelmente à espera
O código de amostra é uma lógica de série típico, parse_1 passa URL e o número de ciclos até à parse_2, pedido parse_2 e devolve o estado parse_1 Código continuar a iteração passo foi repetido uma vez antes da
Em terceiro lugar, multi-threaded
Porque existe apenas um segmento de tempo de CPU em cada escala na execução do programa, de modo roscado multi-processo aumenta realmente o uso resultando na melhoria da utilização da CPU
bibliotecas multi-threaded tem um monte de, aqui concurrent.futures em ThreadPoolExecutor para demonstrar. biblioteca Introdução ThreadPoolExecutor porque é mais concisa do que qualquer outro código da biblioteca
Por conveniência de ilustração, o seguinte código se ele é recém-partes acrescentou, a primeira linha de código mais> Símbolo facilitar a observação de ilustração, a necessidade operação real a ser removido
solicitações de importação
> A partir concurrent.futures importação ThreadPoolExecutor
parse_1 def ():
url = 'https://www.baidu.com'
# Criar pool de threads
> Piscina = ThreadPoolExecutor (6)
para i na gama (300):
> Pool.submit (parse_2, url)
> Pool.shutdown (espera = True)
def parse_2 (url):
= resposta requests.get (URL)
print (response.status_code)
se __name__ == '__main__':
parse_1 ()
A sincronização é assíncrono com o parente. Asynchronous é independente um do outro, continuar a fazer sua própria coisa enquanto espera para um evento, você não precisa esperar para este evento após a conclusão da obra. fio Asynchronous é alcançar uma forma, que é o processamento assíncrono meio-threading multi-assíncronos que não sei os resultados, às vezes precisamos de saber os resultados, você pode usar um callback
solicitações de importação
de concurrent.futures ThreadPoolExecutor importação
# Adicionar uma função de retorno
> Def callback (futuro):
> Print (future.result ())
parse_1 def ():
url = 'https://www.baidu.com'
piscina = ThreadPoolExecutor (6)
para i na gama (300):
> Resultados = pool.submit (parse_2, url)
# passos fundamentais Callback
> Results.add_done_callback (callback)
pool.shutdown (espera = True)
def parse_2 (url):
= resposta requests.get (URL)
print (response.status_code)
se __name__ == '__main__':
parse_1 ()
P ython um multi-threaded inúmeras pessoas têm criticado GIL (Global Interpreter Lock), mas pertencem a tarefa de multi-threaded IO-intensiva ainda é muito adequado para rastreamento das páginas deste maioria.
Em quarto lugar, multi-processo
Multi-processo implementado de duas maneiras: ProcessPoolExecutor e multiprocessamento
1. ProcessPoolExecutor
E semelhante ThreadPoolExecutor rosca-multi
solicitações de importação
> A partir concurrent.futures importar ProcessPoolExecutor
parse_1 def ():
url = 'https://www.baidu.com'
# Criar pool de threads
> Piscina = ProcessPoolExecutor (6)
para i na gama (300):
> Pool.submit (parse_2, url)
> Pool.shutdown (espera = True)
def parse_2 (url):
= resposta requests.get (URL)
print (response.status_code)
se __name__ == '__main__':
parse_1 ()
Procure alterações em nome de duas classes, o código ainda é muito simples, empatia também pode adicionar uma função de retorno
solicitações de importação
de concurrent.futures ProcessPoolExecutor importação
> Def callback (futuro):
> Print (future.result ())
parse_1 def ():
url = 'https://www.baidu.com'
piscina = ProcessPoolExecutor (6)
para i na gama (300):
> Resultados = pool.submit (parse_2, url)
> Results.add_done_callback (callback)
pool.shutdown (espera = True)
def parse_2 (url):
= resposta requests.get (URL)
print (response.status_code)
se __name__ == '__main__':
parse_1 ()
2. multiprocessamento
olhar directo sobre o código, tudo nos comentários.
solicitações de importação
> De multiprocessamento importação Piscina
parse_1 def ():
url = 'https://www.baidu.com'
# Piscina construída
> Piscina = Piscina (processos = 5)
# resultados Armazene
> Res_lst = []
para i na gama (300):
# Junte-se à piscina tarefa
> Res = pool.apply_async (func = parse_2, args = (url,))
# Resultado Aquisição concluída (necessidade de remover)
> res_lst.append (res)
# Armazenar o resultado final (também podem ser armazenados diretamente ou impressão)
> Good_res_lst = []
> Para res em res_lst:
# Obter resultados depois de usar o processo de aquisição
> Good_res = res.get ()
# Resultado de julgamento é bom ou ruim
> Se good_res:
> good_res_lst.append (good_res)
# Desligue e aguardar a conclusão
> Pool.close ()
> Pool.join ()
def parse_2 (url):
= resposta requests.get (URL)
print (response.status_code)
se __name__ == '__main__':
parse_1 ()
Você pode ver a biblioteca de código multiprocessamento um pouco entediante, mas suportar mais expansão. Multi-processo e multi-threading pode realmente atingir o objectivo de acelerar, mas se eles estão bloqueando fio IO ou processo será um desperdício, para que haja uma maneira melhor ......
Quinto, assíncrona sem bloqueio
Coroutine + retorno de chamada com dinâmica não-bloqueio colaboração assíncrona podemos alcançar o propósito, a natureza tomou apenas um segmento, de modo a um grande escopo de uso de recursos
Clássico é o uso de assíncrona sem bloqueio asyncio rendimento + biblioteca, a fim de facilitar o uso do surgimento gradual de uma aiohttp pacote mais superior, a fim de melhor compreender a biblioteca asyncio melhor compreensão sem bloqueio assíncrono. E GEvent é um muito fácil de implementar biblioteca coroutine
solicitações de importação
> De macaco importação GEvent
# Alma Macaco patch é executado em colaboração
> Monkey.patch_all ()
> Import vendia
parse_1 def ():
url = 'https://www.baidu.com'
# Criar uma lista de tarefas
> Tasks_list = []
para i na gama (300):
> Task = gevent.spawn (parse_2, url)
> Tasks_list.append (tarefa)
> Gevent.joinall (tasks_list)
def parse_2 (url):
= resposta requests.get (URL)
print (response.status_code)
se __name__ == '__main__':
parse_1 ()
GEvent pode muito a velocidade, também introduz um novo problema: se não quiser rápido demais para causar muita carga sobre o servidor como fazer? Se é um multi-processo de construção de multi-threaded da piscina, você pode controlar o número de piscina. Se você quiser controlar a velocidade com GEvent também tem uma boa abordagem: fila de construção. GEvent também forneceu classe Quene, altere o seguinte código maior
solicitações de importação
de macaco importação GEvent
monkey.patch_all ()
importação vendia
> De importação gevent.queue Queue
parse_1 def ():
url = 'https://www.baidu.com'
= Tasks_list []
# Fila de instanciação
> Quene = Fila ()
para i na gama (300):
Todas as filas pressionado url #
> Quene.put_nowait (url)
fila de dois #
> Para _ na faixa (2):
> Task = gevent.spawn (parse_2)
> Tasks_list.append (tarefa)
gevent.joinall (tasks_list)
# Não precisa passar parâmetros, que estão na fila
> Def parse_2 ():
# Ciclo se a fila está vazia
> Enquanto não quene.empty ():
# Pop fila
> Url = quene.get_nowait ()
= resposta requests.get (URL)
Analisando o status da fila #
> Print (quene.qsize (), response.status_code)
se __name__ == '__main__':
parse_1 ()
conclusão
Estes encontram-se vários método de aceleração comumente usado. Se você estiver interessado pode utilizar módulo de teste do código de tempo determina o tempo de execução. Acelerar o réptil é uma habilidade importante, mas a velocidade é controlada adequadamente trabalhadores répteis bons hábitos, não dar demasiada pressão sobre o servidor, bye ~
Mais diversão Código de caixa grupo aditivo: 850591259