基础篇(7)多线线程+对象实现爬虫

本文介绍了一个使用Python多线程技术实现的图片爬虫项目,通过解析网页源码,提取图片链接并下载到本地。项目运用了requests库进行网络请求,lxml库解析HTML,以及threading库实现多线程并发。

 

 

import time
import random
import re
import os
from urllib import request
import requests
import threading
from lxml import etree
from queue import Queue  # 这个队列是线程队列
"""
多线程的Queue就是线程安全的,所有我们不用考虑锁的问题
"""

class Procuder(threading.Thread):
    """
    生成者继承threading.Thread需要实现__init__方法和run()
    """
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
    }
    def __init__(self,url_queue,img_queue,*args,**kwargs):
        """
        :param url_queue: url地址队列
        :param img_queue: 图片地址队列
        :param args: threading.Thread类的元组参数
        :param kwargs: threading.Thread的字典参数
        """
        super(Procuder,self).__init__(*args,**kwargs)
        self.url_queue =url_queue
        self.img_queue =img_queue
    def run(self):
        while True:
            if self.url_queue.empty():
                break
            url =self.url_queue.get() # 从队列中获取一个url
            self.parse_page(url)
    def parse_page(self,url):
        response = requests.get(url,headers=self.headers)
        if response.status_code==200:
            text = response.text
            html = etree.HTML(text)
            imgs = html.xpath("//div[@class='page-content text-center']//img[@class!='gif']")
            for img in imgs:
                img_url = img.get("data-original")
                alt = img.get("alt")
                alt = re.sub(r'[\.\*\?。?!!,,]',"",alt)
                suffix = os.path.splitext(img_url)[1]
                file_name = alt +suffix
                self.img_queue.put((img_url,file_name))


class Consumer(threading.Thread):
    def __init__(self,url_queue,img_queue,*args,**kwargs):
        super(Consumer,self).__init__(*args,**kwargs)
        self.url_queue = url_queue
        self.img_queue = img_queue
    def run(self):
        while True:
            if self.url_queue.empty() and self.img_queue.empty():
                break
            img_url, filename = self.img_queue.get()
            request.urlretrieve(img_url, 'images/' + filename)
            print(filename + '  下载完成!')
def main():
    url_queue = Queue(100)
    img_queue = Queue(1000)
    for page in range(1,101):
        url = "http://www.doutula.com/photo/list/?page={}".format(str(page))
        url_queue.put(url)
    for i in range(5):
        p_thrd = Procuder(url_queue,img_queue)
        p_thrd.start()
    for j in range(10):
        c_thrd = Consumer(url_queue,img_queue)
        c_thrd.start()
if __name__ == '__main__':
    main()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值