python多线程爬取段子_多线程-实战-爬取段子

#coding=utf-8

'''

多线程爬取糗百的段子

分析网页:

https://www.qiushibaike.com/8hr/page/1/ 第一页

https://www.qiushibaike.com/8hr/page/2/ 第二页

https://www.qiushibaike.com/8hr/page/3/ 第三页

'''

import threading

import requests

import time

import queue

from lxml import html

import traceback

#定义线程1:从页码队列获取每页url爬取每页内容存至数据队列

class thread1(threading.Thread):

def __init__(self,pageQueue,dataQueue,threadName):

threading.Thread.__init__(self)

self.pageQueue=pageQueue #页码队列

self.dataQueue=dataQueue #每页数据队列

self.threadName=threadName #线程名称

self.headers = {

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) \

Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"

}

def run(self):

print('采集线程开始',self.threadName)

try:

#判断页码队列不为空时才开始循环

while not flag1:

pageindex=self.pageQueue.get()

url="https://www.qiushibaike.com/8hr/page/"+str(pageindex)+"/"

#请求每页糗百获取每页结果

res=requests.get(url,headers=self.headers).text

#小技巧,当请求每页时停留0.5秒,以免出现还未请求完成就开始存入队列出现异常

time.sleep(0.5)

self.dataQueue.put(res)

except Exception as e:

print(e)

traceback.print_exc(e)

print('采集线程结束',self.threadName)

#定义线程2:从数据队列爬取每条段子存至文件

class thread2(threading.Thread):

def __init__(self,dataQueue,filename,threadName):

threading.Thread.__init__(self)

self.dataQueue=dataQueue #每页数据队列

self.filename=filename #文件名

self.threadName=threadName #线程名称

def run(self):

print('解析线程开始',self.threadName)

try:

#判断数据列不为空时才开始循环

while not flag2:

data=self.dataQueue.get()

htmldata=html.etree.HTML(data)

result=htmldata.xpath('//div//a[@class="recmd-content"]')

for data in result:

data=data.text

self.filename.write(data)

self.filename.write('\n')

except Exception as e:

print(e)

traceback.print_exc(e)

print('解析线程结束',self.threadName)

#判断页码队列是否为空的标记

flag1=False

#判断数据队列是否为空的标记

flag2=False

#定义主方法

def main():

#定义页码队列

pageQueue=queue.Queue(10)

#页码队列里存入10个数当做每页的页码

for i in range(1,11):

pageQueue.put(i)

#定义数据队列

dataQueue=queue.Queue()

with open('duanzi.txt','a',encoding='utf-8') as filename:

#定义采集子线程并启动

t1=thread1(pageQueue,dataQueue,'thread-1')

t1.start()

#定义解析子线程并启动

t2=thread2(dataQueue,filename,'thread-2')

t2.start()

#主线程:判断页码队列是否为空

#当为空时pageQueue.empty()返回True,当不为空时返回False

#所以当不为空时,这个主线程会阻塞在这里

while not pageQueue.empty():

pass

#当pageQueue为空后,就退出了上述循环执行如下:

global flag1

flag1=True

#主线程同理:判断数据队列是否为空

while not dataQueue.empty():

pass

global flag2

flag2=True

'''

注:子线程t1、t2 和 主线程两个while语句是各自并行执行各自

'''

t1.join()

t2.join()

print('主线程结束,采集解析结束')

if __name__=='__main__':

main()

方式二

#coding=utf-8

#coding=utf-8

'''

多线程爬取糗百的段子

分析网页:

https://www.qiushibaike.com/8hr/page/1/ 第一页

https://www.qiushibaike.com/8hr/page/2/ 第二页

https://www.qiushibaike.com/8hr/page/3/ 第三页

'''

import threading

import requests

import time

import queue

from lxml import html

import traceback

#定义请求每页的数据,并写入到数据队列

def getPage(pageQueue,dataQueue,headers):

print('采集线程开始:{}'.format(threading.current_thread().getName()))

try:

# 判断页码队列不为空时才开始循环

while not flag1:

pageindex = pageQueue.get()

url = "https://www.qiushibaike.com/8hr/page/" + str(pageindex) + "/"

# 请求每页糗百获取每页结果

res = requests.get(url, headers=headers).text

# 小技巧,当请求每页时停留0.5秒,以免出现还未请求完成就开始存入队列出现异常

time.sleep(0.5)

dataQueue.put(res)

except Exception as e:

print(e)

traceback.print_exc(e)

print('采集线程结束:{}'.format(threading.current_thread().getName()))

#定义解析获取每页里每条段子

def getData(dataQueue,filename):

print('解析线程开始:{}'.format(threading.current_thread().getName()))

try:

# 判断数据列不为空时才开始循环

while not flag2:

data = dataQueue.get()

htmldata = html.etree.HTML(data)

result = htmldata.xpath('//div//a[@class="recmd-content"]')

for data in result:

data = data.text

filename.write(data)

filename.write('\n')

except Exception as e:

print(e)

traceback.print_exc(e)

print('解析线程结束:{}'.format(threading.current_thread().getName()))

#定义线程1:从页码队列获取每页url爬取每页内容存至数据队列

class thread1(threading.Thread):

def __init__(self,func,name,args):

#super().__init__(target=func,name=name,args=args)

# 或如下:显示调用父类构造方法

threading.Thread.__init__(self,target=func,name=name,args=args)

def run(self):

self._target(*self._args)

#定义线程2:从数据队列爬取每条段子存至文件

class thread2(threading.Thread):

def __init__(self,func,name,args):

#super().__init__(target=func,name=name,args=args)

#或如下:显示调用父类构造方法

threading.Thread.__init__(self, target=func, name=name, args=args)

def run(self):

self._target(*self._args)

#判断页码队列是否为空的标记

flag1=False

#判断数据队列是否为空的标记

flag2=False

#定义主方法

def main():

headers={

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) \

Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"

}

#定义页码队列

pageQueue=queue.Queue(10)

#页码队列里存入10个数当做每页的页码

for i in range(1,11):

pageQueue.put(i)

#定义数据队列

dataQueue=queue.Queue()

with open('duanzi2.txt','a',encoding='utf-8') as filename:

#定义采集子线程并启动

t1=thread1(getPage,'thread-1',(pageQueue,dataQueue,headers))

t1.start()

#定义解析子线程并启动

t2=thread2(getData,'thread-2',(dataQueue,filename))

t2.start()

#主线程:判断页码队列是否为空

#当为空时pageQueue.empty()返回True,当不为空时返回False

#所以当不为空时,这个主线程会阻塞在这里

while not pageQueue.empty():

pass

#当pageQueue为空后,就退出了上述循环执行如下:

global flag1

flag1=True

#主线程同理:判断数据队列是否为空

while not dataQueue.empty():

pass

global flag2

flag2=True

'''

注:子线程t1、t2 和 主线程两个while语句是各自并行执行各自

'''

t1.join()

t2.join()

print('主线程结束,采集解析结束')

if __name__=='__main__':

main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值