标签:join global src false lxml exce info exiting 队列
学习爬虫,其乐无穷!
今天给大家带来一个爬虫案例,爬取糗事百科搞笑内涵段子。
爬取糗事百科段?,假设??的 URL 是:http://www.qiushibaike.com/8hr/page/1
参考代码:
#qiushibaike.py #import urllib #import re #import chardet import requests from lxml import etree page = 1 url = ‘http://www.qiushibaike.com/8hr/page/‘ + str(page) headers = { ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit /537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36‘, ‘Accept-Language‘: ‘zh-CN,zh;q=0.8‘} try: response = requests.get(url, headers=headers) 167 resHtml = response.text html = etree.HTML(resHtml) result = html.xpath(‘//div[contains(@id,"qiushi_tag")]‘) for site in result: item = {} imgUrl = site.xpath(‘./div/a/img/@src‘)[0].encode(‘utf-8‘) username = site.xpath(‘./div/a/@title‘)[0].encode(‘utf-8‘) #username = site.xpath(‘.//h2‘)[0].text content = site.xpath(‘.//div[@class="content"]/span‘)[0].te xt.strip().encode(‘utf-8‘) # 投票次数 vote = site.xpath(‘.//i‘)[0].text #print site.xpath(‘.//*[@class="number"]‘)[0].text # 评论信息 comments = site.xpath(‘.//i‘)[1].text print imgUrl, username, content, vote, comments except Exception, e: print e
演示效果:
Queue(队列对象):
Queue 是 python 中的标准库,可以直接 import Queue 引?;队列是线程间最常?的交换数据的形式python 下多线程的思考 对于资源,加锁是个重要的环节。因为 python 原?的list,dict 等,都是 not thread safe 的。?Queue,是线程安全的,因此在满?使?条件下,建议使?队列。
Queue.qsize() 返回队列的??
Queue.empty() 如果队列为空,返回 True,反之 False
Queue.full() 如果队列满了,返回 True,反之 False
Queue.full 与 maxsize ??对应
Queue.get([block[, timeout]])获取队列,timeout 等待时间
多线程示意图:
如需要python爬虫全套完整的入门到项目实战视频教程,请点:爬虫视频教程。
参考代码:
# -*- coding:utf-8 -*- import requests from lxml import etree from Queue import Queue import threading import time import json class thread_crawl(threading.Thread): ‘‘‘ 抓取线程类 ‘‘‘ def init (self, threadID, q): threading.Thread. init (self) self.threadID = threadID self.q = q def run(self): print "Starting " + self.threadID self.qiushi_spider() print "Exiting ", self.threadID def qiushi_spider(self): # page = 1 while True: if self.q.empty(): break else: page = self.q.get() print ‘qiushi_spider=‘, self.threadID, ‘,page=‘, str(page) url = ‘http://www.qiushibaike.com/hot/page/‘ + str( page) + ‘/‘ headers = { ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; WO W64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Sa fari/537.36‘, ‘Accept-Language‘: ‘zh-CN,zh;q=0.8‘} # 多次尝试失败结束、防?死循环 timeout = 4 while timeout > 0: timeout -= 1 try: content = requests.get(url, headers=headers ) data_queue.put(content.text) break except Exception, e: print ‘qiushi_spider‘, e if timeout < 0: print ‘timeout‘, url class Thread_Parser(threading.Thread): ‘‘‘ ??解析类; ‘‘‘ def init (self, threadID, queue, lock, f): threading.Thread. init (self) self.threadID = threadID self.queue = queue self.lock = lock self.f = f def run(self): print ‘starting ‘, self.threadID global total, exitFlag_Parser while not exitFlag_Parser: try: ‘‘‘ 调?队列对象的 get()?法从队头删除并返回?个项?。可选参 数 为 block,默认为 True。 如果队列为空且 block 为 True,get()就使调?线程暂停,直? 有项?可?。 otal 如果队列为空且 block 为 False,队列将引发 Empty 异常。 ‘‘‘ item = self.queue.get(False) if not item: pass self.parse_data(item) self.queue.task_done() print ‘Thread_Parser=‘, self.threadID, ‘,total=‘, t except: pass print ‘Exiting ‘, self.threadID def parse_data(self, item): ‘‘‘ 解析??函数 :param item: ??内容 :return: ‘‘‘ global total try: html = etree.HTML(item) result = html.xpath(‘//div[contains(@id,"qiushi_tag")]‘ ) for site in result: try: imgUrl = site.xpath(‘.//img/@src‘)[0] title = site.xpath(‘.//h2‘)[0].text content = site.xpath(‘.//div[@class="content"]/ span‘)[0].text.strip() vote = None comments = None try: vote = site.xpath(‘.//i‘)[0].text comments = site.xpath(‘.//i‘)[1].text except: pass result = { ‘imgUrl‘: imgUrl, ‘title‘: title, ‘content‘: content, ‘vote‘: vote, ‘comments‘: comments, } with self.lock: # print ‘write %s‘ % json.dumps(result) self.f.write(json.dumps(result, ensure_asci i=False).encode(‘utf-8‘) + "\n") except Exception, e: print ‘site in result‘, e except Exception, e: print ‘parse_data‘, e with self.lock: total += 1 data_queue = Queue() exitFlag_Parser = False lock = threading.Lock() total = 0 def main(): output = open(‘qiushibaike.json‘, ‘a‘) #初始化???码 page 从 1-10 个?? pageQueue = Queue(50) for page in range(1, 11): pageQueue.put(page) #初始化采集线程 crawlthreads = [] crawlList = ["crawl-1", "crawl-2", "crawl-3"] for threadID in crawlList: thread = thread_crawl(threadID, pageQueue) thread.start() crawlthreads.append(thread) #初始化解析线程 parserList parserthreads = [] parserList = ["parser-1", "parser-2", "parser-3"] #分别启动 parserList for threadID in parserList: thread = Thread_Parser(threadID, data_queue, lock, output) thread.start() parserthreads.append(thread) # 等待队列清空 while not pageQueue.empty(): pass # 等待所有线程完成 for t in crawlthreads: t.join() while not data_queue.empty(): pass # 通知线程是时候退出 global exitFlag_Parser exitFlag_Parser = True for t in parserthreads: t.join() print "Exiting Main Thread" with lock: output.close() if name == ‘ main ‘: main()
1、爬取笔趣?某部?说的所有页面。
2、国家?品药品监督管理总局:http://app1.sfda.gov.cn 采集分类 国产药品商品名(6994) 下的所有的商品信息。
这个大家可以试着做一做,如需爬虫视频详解,请点爬虫视频。
标签:join global src false lxml exce info exiting 队列
原文地址:https://www.cnblogs.com/shsxt/p/13560682.html