美文网首页
多线程爬虫

多线程爬虫

作者: 马本不想再等了 | 来源:发表于2019-02-23 15:50 被阅读0次

1. 多线程爬虫基本思路图

分布式爬虫流程.png

爬取犯贱网图片,案例源码如下:

import threading
import time
from queue import Queue
import requests
from lxml import etree
import json


# 用来存放采集线程
g_crawl_list = []
# 用来存放解析线程
g_parse_list = []

class CrawlThread(threading.Thread):
    def __init__(self, name, page_queue, data_queue):
        super(CrawlThread, self).__init__()
        self.name = name
        self.page_queue = page_queue
        self.data_queue = data_queue
        self.url = 'http://www.fanjian.net/jiantu-{}'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
        }

    def run(self):
        print('%s----线程启动' % self.name)
        while 1:
            # 判断采集线程何时退出
            if self.page_queue.empty():
                break
            # 从队列中取出页码
            page = self.page_queue.get()
            # 拼接url,发送请求
            url = self.url.format(page)
            r = requests.get(url, headers=self.headers)
            # 响应内容存放到data_queue中
            self.data_queue.put(r.text)
        print('%s----线程结束' % self.name)

class ParserThread(threading.Thread):
    def __init__(self, name, data_queue, fp, lock):
        super(ParserThread, self).__init__()
        self.name = name
        self.data_queue = data_queue
        self.fp = fp
        self.lock = lock

    def run(self):
        print('%s----线程启动' % self.name)
        while 1:
            try:
                # 从data_queue中取出一页数据
                data = self.data_queue.get(True, 10)
                # 解析内容
                self.parse_content(data)
            except Exception as e:
                break
        print('%s----线程结束' % self.name)

    def parse_content(self, data):
        tree = etree.HTML(data)
        # 获取所有的li
        li_list = tree.xpath("//ul[@class='cont-list']/li")
        items = []
        for li in li_list:
            # 获取图片标题
            title = li.xpath(".//h2/a/text()")[0]
            # 获取图片url,这里注意懒加载,要获取data-src
            image_url = li.xpath(".//div[contains(@class, 'cont-list-main')]/p/img/@data-src")
            item = {
                '标题': title,
                '连接': image_url
            }
            items.append(item)
        # 写到文件中
        self.lock.acquire()
        self.fp.write(json.dumps(items, ensure_ascii=False) + '\n')
        self.lock.release()

# 创建队列
def create_queue():
    # 创建页码队列
    page_queue = Queue()
    for page in range(1, 50):
        page_queue.put(page)
    # 创建内容队列
    data_queue = Queue()
    return page_queue, data_queue

# 创建采集线程
def create_crawl_thread(page_queue, data_queue):
    crawl_name = ['采集线程1', '采集线程2', '采集线程3']
    for name in crawl_name:
        # 创建一个采集线程
        tcrwal = CrawlThread(name, page_queue, data_queue)
        # 保存到列表中
        g_crawl_list.append(tcrwal)

# 创建解析线程
def create_parse_thread(data_queue, fp, lock):
    parse_name = ['解析线程1', '解析线程2', '解析线程3']
    for name in parse_name:
        # 创建一个解析线程
        tparse = ParserThread(name, data_queue, fp, lock)
        # 保存到列表中
        g_parse_list.append(tparse)

def main():
    # 创建队列函数
    page_queue, data_queue = create_queue()
    # 打开文件
    fp = open('jian.json', 'a', encoding='utf-8')
    # 创建锁
    lock = threading.Lock()
    # 创建采集线程
    create_crawl_thread(page_queue, data_queue)
    time.sleep(3)
    # 创建解析线程
    create_parse_thread(data_queue, fp, lock)
    # 启动所有采集线程
    for tcrwal in g_crawl_list:
        tcrwal.start()
    # 启动所有解析线程
    for tparse in g_parse_list:
        tparse.start()
    # 主线程等待子线程结束
    for tcrwal in g_crawl_list:
        tcrwal.join()
    for tparse in g_parse_list:
        tparse.join()

    # 关闭文件
    fp.close()
    print('主线程子线程全部结束')

if __name__ == '__main__':
    main() 

笔者小白一枚,如有纰漏,还请各位读者指点。

相关文章

  • Python爬虫第七天:多线程爬虫|Scrapy框架

    内容简述: 一:多线程爬虫 二:Scrapy框架 一:多线程爬虫原理 【示例见代码】 二:Scrapy框架...

  • Python爬虫基础教程(三)

    九、多线程爬虫 9.1利用多线程爬虫爬取糗事百科的资源: 十、爬虫代码总结: 要实现一个完整的爬虫,无外乎4...

  • 「爬虫」12爬虫之多线程爬虫

    1.多线程爬虫 多线程就是程序中的某些程序段并行执行,合理地设置多线程,可以让爬虫效率更高。 2.单线程实例 以爬...

  • Thread

    队列 线程锁 多线程,线程池 队列 多线程爬虫示例 多线程 自定义线程 线程池

  • [CP_12] Python多线程爬虫应用实践(社招职位名称获取

    目录结构 一、多线程爬虫的使用 1. 多线程实现 <关联> [Pt_04] Python进程|多进程|线程|多线程...

  • 爬虫基础05

    多线程爬虫 队列(from multiprocessing import Queue)UrlQueue = Que...

  • 男子大学生的無駄日常

    关键词:Python,爬虫,requests,BeautifulSoup,opencv,python多线程,正则表...

  • 多线程爬虫实战——爬取糗事百科

    多线程爬虫思路 我们之前写的爬虫网页,往往是等待一页内容爬取完毕后,再爬取另一页内容,效率很低,而用多线程和队列之...

  • 多线程爬虫

    1、多线程爬虫,可考虑放到线程池,把我们需要解析的URL 地址存入我们的队列中,然后去触发多线程进行操作、 代码如...

  • 多线程爬虫

    多线程爬虫 有些时候,比如下载图片,因为下载图片是一个耗时的操作。如果采用之前那种同步的方式下载。那效率肯会特别慢...

网友评论

      本文标题:多线程爬虫

      本文链接:https://www.haomeiwen.com/subject/wncpyqtx.html