2019-06-17多线程爬虫

分析:
两类线程:下载(3),解析(3)
内容队列:下载线程往队列中put数据,解析线程从队列get数据
url队列:下载线程从url队列get数据
写数据:上锁
案例代码:

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

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

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

class CrawlThread(threading.Thread):
    """docstring fos CrawlThread"""
    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 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 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 ParseThread(threading.Thread):
    """docstring fos CrawlThread"""
    def __init__(self, name,data_queue,fp,lock):
        super(ParseThread, 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:
            # if self.data_queue.empty():
            #   break
            #从data_queue中取出一页数据
            data=self.data_queue.get(True,10)
            #解析内容即可

            self.page_content(data)
        print('%s---------线程结束' % self.name)
    def page_content(self,data):
        
        tree=etree.HTML(data)
        #先找所有的li,再从li里面找自己的标题和url
        
        li_list=tree.xpath('//ul[@class="cont-list"]/li')
    
        items=[]
        for oli in li_list: 
        #获取标题
            title=oli.xpath('.//h2/a/text()')[0]
        #获取图片url
            url_page=oli.xpath('.//div[@class="cont-list-main"]//img/@data-src')
            item={
            '标题': title,
            '链接':url_page
            }
            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,6):
        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:
        #创建一个采集线程
        tcrawl=CrawlThread(name,page_queue,data_queue)
        #保存到列表中
        g_crawl_list.append(tcrawl)

def create_parse_thread(data_queque,fp,lock):
    parse_name = ['解析线程1号','解析线程2号','解析线程3号']
    for name in parse_name:
        #创建一个解析线程
        tparse=ParseThread(name,data_queque,fp,lock)
        #保存到列表中
        g_parse_list.append(tparse)
def main():
    #创建队列
    page_queue,data_queue = create_queue()
    #打开文件
    
    fp=open('jian.json','a',encoding='utf8')
    #创建锁
    lock=threading.Lock()
    #创建采集线程
    create_crawl_thread(page_queue,data_queue)
    time.sleep(3)

    #创建解析线程
    create_parse_thread(data_queue,fp,lock)

    #启动所有采集线程
    for tcrawl in g_crawl_list:
        tcrawl.start()
    #启动所有解析线程
    for tparse in g_parse_list:
        tparse.start()

    #主线程等待子线程结束
    for tcrawl in g_crawl_list:
        tcrawl.join()
    for tparse in g_parse_list:
        tparse.join()
    #在这里关闭文件
    fp.close()
    print('主线程子线程全部结束')
if __name__ == '__main__':
    main()

显示:


采集线程1号---------线程启动
采集线程2号---------线程启动
采集线程3号---------线程启动
解析线程1号---------线程启动
解析线程2号---------线程启动
解析线程3号---------线程启动
采集线程2号---------线程结束
采集线程1号---------线程结束
采集线程3号---------线程结束
Exception in thread 解析线程3号:
Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\threading.py", line 917, in _bootstrap_inner
    self.run()
  File "E:\Sublime Text 3\day1\2_xincheng.py", line 56, in run
    data=self.data_queue.get(True,10)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\queue.py", line 178, in get
    raise Empty
_queue.Empty

Exception in thread 解析线程1号:
Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\threading.py", line 917, in _bootstrap_inner
    self.run()
  File "E:\Sublime Text 3\day1\2_xincheng.py", line 56, in run
    data=self.data_queue.get(True,10)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\queue.py", line 178, in get
    raise Empty
_queue.Empty

Exception in thread 解析线程2号:
Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\threading.py", line 917, in _bootstrap_inner
    self.run()
  File "E:\Sublime Text 3\day1\2_xincheng.py", line 56, in run
    data=self.data_queue.get(True,10)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\queue.py", line 178, in get
    raise Empty
_queue.Empty

主线程子线程全部结束
[Finished in 15.1s]

报错代码待优化...
json数据


image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容