1. Descripción del requisito
Figura que se arrastra dirección del sitio web es la lucha:https://www.doutula.com/photo/list/, Sitio web siguiente captura de pantalla:
Ahora tenemos que tomar la primera subida de la página 2 del paquete de expresión, entonces el siguiente directamente en el código.
2. Código de combate
2,1 rastreo de un solo subproceso
from urllib import request
import requests
from lxml import etree
import re
import os
HEADERS= {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
def parse_url(url):
response = requests.get(url, headers=HEADERS)
text = response.text
html_str = etree.HTML(text)
imgs = html_str.xpath('//div[@class="page-content text-center"]//a/img[@class!="gif"]')
for img in imgs:
img_url = img.get('data-original')
alt = img.get('alt')
# 替换alt中的特殊字符
alt = re.sub(r'[\?\?\.,。,!!/]','',alt)
# 提取后缀名
suffix = os.path.splitext(img_url)[1]
filename = alt + suffix
print("正在下载:" + filename)
request.urlretrieve(img_url,'image/'+filename)
def main():
for i in range(1,3):
base_url = 'https://www.doutula.com/photo/list/?page={}'.format(i)
parse_url(base_url)
if __name__ == '__main__':
main()
rastreo de una sola rosca, entonces hay un problema, demasiado lento para descargar el paquete de expresión, como una por una descarga. Para resolver este problema, puede utilizar varios subprocesos para resolver este problema.
hilo versión Más de 2,2
# Author:Logan
from urllib import request
import requests
from lxml import etree
import re
import os
from queue import Queue
import threading
# 定义生产者
class Procuder(threading.Thread):
HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
def __init__(self, page_queue, img_queue, *args, **kwargs):
super(Procuder, self).__init__( *args, **kwargs)
self.page_queue = page_queue
self.img_queue = img_queue
def run(self):
while True:
if self.page_queue.empty():
break
url = self.page_queue.get()
self.parse_url(url)
def parse_url(self,url):
response = requests.get(url, headers=self.HEADERS)
text = response.text
html_str = etree.HTML(text)
imgs = html_str.xpath('//div[@class="page-content text-center"]//a/img[@class!="gif"]')
for img in imgs:
img_url = img.get('data-original')
alt = img.get('alt')
# 替换alt中的特殊字符
alt = re.sub(r'[\?\?\.,。,!!/*]', '', alt)
# 提取后缀名
suffix = os.path.splitext(img_url)[1]
filename = alt + suffix
self.img_queue.put((filename,img_url))
self.page_queue.task_done() # 让队列计数减一
class Counsumer(threading.Thread):
def __init__(self, page_queue, img_queue, *args, **kwargs):
super(Counsumer, self).__init__(*args, **kwargs)
self.page_queue = page_queue
self.img_queue = img_queue
def run(self):
print("============")
while True:
if self.img_queue.empty() and self.page_queue.empty():
break
filename,img_url = self.img_queue.get()
request.urlretrieve(img_url,'image/'+filename)
print("下载完成:%s" %filename)
self.img_queue.task_done()
def main():
page_queue =Queue(100)
img_queue = Queue(1000)
for i in range(1,2):
base_url = 'https://www.doutula.com/photo/list/?page={}'.format(i)
page_queue.put(base_url)
for i in range(5):
t1 = Procuder(page_queue, img_queue)
t1.start()
t1.join()
for i in range(5):
t2 = Counsumer(page_queue, img_queue)
t2.start()
t2.join() # 让主线程阻塞(等待子线程结束在结束)
if __name__ == '__main__':
main()
Si el hilo tomada de cada cola, pero sin task_done ejecución (), y luego unirse a la cola no puede determinar al final no hay fin, en la implementación definitiva de un join () no puede esperar a los resultados, habría sido suspendido. Como se apreciará, una vez cada task_done elimina de un elemento de la cola, de modo que cuando el último para unirse a la final de acuerdo a si la longitud de la cola de la cola es cero, por lo que la ejecución del hilo principal.