Python实现多线程抓取妹子图,python多线程

by admin on 2019年11月12日

Python中的八线程未有真的实现多现程!
为啥那样说,大家精通多个概念,全局解释器锁(GIL卡塔尔国。

Python七十四线程完毕联机的各类办法,python四线程

临界财富即这么些二次只好被二个线程访谈的能源,标准例子就是打字与印刷机,它二次只可以被二个程序用来施行打字与印刷成效,因为不能够四个线程同期操作,而访谈那有的财富的代码常常称得上临界区。

锁机制

threading的Lock类,用该类的acquire函数举办加锁,用realease函数举行解锁

import threading
import time

class Num:
  def __init__(self):
    self.num = 0
    self.lock = threading.Lock()
  def add(self):
    self.lock.acquire()#加锁,锁住相应的资源
    self.num += 1
    num = self.num
    self.lock.release()#解锁,离开该资源
    return num

n = Num()
class jdThread(threading.Thread):
  def __init__(self,item):
    threading.Thread.__init__(self)
    self.item = item
  def run(self):
    time.sleep(2)
    value = n.add()#将num加1,并输出原来的数据和+1之后的数据
    print(self.item,value)

for item in range(5):
  t = jdThread(item)
  t.start()
  t.join()#使线程一个一个执行

当三个线程调用锁的acquire()方法获得锁时,锁就进入“locked”状态。每一趟独有一个线程能够拿到锁。借使当时另三个线程试图拿走那些锁,该线程就能成为“blocked”状态,称为“同步阻塞”(参见多线程的基本概念卡塔尔。

截止全部锁的线程调用锁的release()方法释放锁之后,锁步向“unlocked”状态。线程调治程序从处于同步梗塞状态的线程中精选多少个来拿到锁,并使得该线程进入运营(running卡塔 尔(阿拉伯语:قطر‎状态。

信号量

能量信号量也提供acquire方法和release方法,每当调用acquire方法的时候,若是中间流速計大于0,则将其减1,假使内部流量计等于0,则会拥塞该线程,知道有线程调用了release方法将内部流速计更新到过量1职位。

import threading
import time
class Num:
  def __init__(self):
    self.num = 0
    self.sem = threading.Semaphore(value = 3)
    #允许最多三个线程同时访问资源

  def add(self):
    self.sem.acquire()#内部计数器减1
    self.num += 1
    num = self.num
    self.sem.release()#内部计数器加1
    return num

n = Num()
class jdThread(threading.Thread):
  def __init__(self,item):
    threading.Thread.__init__(self)
    self.item = item
  def run(self):
    time.sleep(2)
    value = n.add()
    print(self.item,value)

for item in range(100):
  t = jdThread(item)
  t.start()
  t.join()

标准剖断

所谓条件变量,即这种体制是在满意了一定的标准后,线程才方可访谈相关的多寡。

澳门威斯尼人平台登陆 ,它选用Condition类来形成,由于它也足以像锁机制这样用,所以它也可能有acquire方法和release方法,何况它还应该有wait,notify,notifyAll方法。

"""
一个简单的生产消费者模型,通过条件变量的控制产品数量的增减,调用一次生产者产品就是+1,调用一次消费者产品就会-1.
"""

"""
使用 Condition 类来完成,由于它也可以像锁机制那样用,所以它也有 acquire 方法和 release 方法,而且它还有
wait, notify, notifyAll 方法。
"""

import threading
import queue,time,random

class Goods:#产品类
  def __init__(self):
    self.count = 0
  def add(self,num = 1):
    self.count += num
  def sub(self):
    if self.count>=0:
      self.count -= 1
  def empty(self):
    return self.count <= 0

class Producer(threading.Thread):#生产者类
  def __init__(self,condition,goods,sleeptime = 1):#sleeptime=1
    threading.Thread.__init__(self)
    self.cond = condition
    self.goods = goods
    self.sleeptime = sleeptime
  def run(self):
    cond = self.cond
    goods = self.goods
    while True:
      cond.acquire()#锁住资源
      goods.add()
      print("产品数量:",goods.count,"生产者线程")
      cond.notifyAll()#唤醒所有等待的线程--》其实就是唤醒消费者进程
      cond.release()#解锁资源
      time.sleep(self.sleeptime)

class Consumer(threading.Thread):#消费者类
  def __init__(self,condition,goods,sleeptime = 2):#sleeptime=2
    threading.Thread.__init__(self)
    self.cond = condition
    self.goods = goods
    self.sleeptime = sleeptime
  def run(self):
    cond = self.cond
    goods = self.goods
    while True:
      time.sleep(self.sleeptime)
      cond.acquire()#锁住资源
      while goods.empty():#如无产品则让线程等待
        cond.wait()
      goods.sub()
      print("产品数量:",goods.count,"消费者线程")
      cond.release()#解锁资源

g = Goods()
c = threading.Condition()

pro = Producer(c,g)
pro.start()

con = Consumer(c,g)
con.start()

一起队列

put方法和task_done方法,queue有三个未产生职分数量num,put依次num+1,task依次num-1.职务都变成时职务完结。

import threading
import queue
import time
import random

'''
1.创建一个 Queue.Queue() 的实例,然后使用数据对它进行填充。
2.将经过填充数据的实例传递给线程类,后者是通过继承 threading.Thread 的方式创建的。
3.每次从队列中取出一个项目,并使用该线程中的数据和 run 方法以执行相应的工作。
4.在完成这项工作之后,使用 queue.task_done() 函数向任务已经完成的队列发送一个信号。
5.对队列执行 join 操作,实际上意味着等到队列为空,再退出主程序。
'''

class jdThread(threading.Thread):
  def __init__(self,index,queue):
    threading.Thread.__init__(self)
    self.index = index
    self.queue = queue

  def run(self):
    while True:
      time.sleep(1)
      item = self.queue.get()
      if item is None:
        break
      print("序号:",self.index,"任务",item,"完成")
      self.queue.task_done()#task_done方法使得未完成的任务数量-1

q = queue.Queue(0)
'''
初始化函数接受一个数字来作为该队列的容量,如果传递的是
一个小于等于0的数,那么默认会认为该队列的容量是无限的.
'''
for i in range(2):
  jdThread(i,q).start()#两个线程同时完成任务

for i in range(10):
  q.put(i)#put方法使得未完成的任务数量+1

如上正是本文的全部内容,希望对我们的求学抱有利于,也希望大家多多关照帮客之家。

临界能源即那二个叁遍只好被三个线程访谈的财富,规范例证正是打字与印刷机,它三次只好被三个程…

Python多线程、异步+多进度爬虫实今世码,python三十二线程

安装Tornado
省事点能够直接用grequests库,上面用的是tornado的异步client。
异步用到了tornado,根据官方文书档案的例子纠正获得两个大约的异步爬虫类。能够参照他事他说加以考查下流行的文书档案学习下。
pip install tornado

异步爬虫

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import time
from datetime import timedelta
from tornado import httpclient, gen, ioloop, queues
import traceback


class AsySpider(object):
  """A simple class of asynchronous spider."""
  def __init__(self, urls, concurrency=10, **kwargs):
    urls.reverse()
    self.urls = urls
    self.concurrency = concurrency
    self._q = queues.Queue()
    self._fetching = set()
    self._fetched = set()

  def fetch(self, url, **kwargs):
    fetch = getattr(httpclient.AsyncHTTPClient(), 'fetch')
    return fetch(url, **kwargs)

  def handle_html(self, url, html):
    """handle html page"""
    print(url)

  def handle_response(self, url, response):
    """inherit and rewrite this method"""
    if response.code == 200:
      self.handle_html(url, response.body)

    elif response.code == 599:  # retry
      self._fetching.remove(url)
      self._q.put(url)

  @gen.coroutine
  def get_page(self, url):
    try:
      response = yield self.fetch(url)
      print('######fetched %s' % url)
    except Exception as e:
      print('Exception: %s %s' % (e, url))
      raise gen.Return(e)
    raise gen.Return(response)

  @gen.coroutine
  def _run(self):
    @gen.coroutine
    def fetch_url():
      current_url = yield self._q.get()
      try:
        if current_url in self._fetching:
          return

        print('fetching****** %s' % current_url)
        self._fetching.add(current_url)

        response = yield self.get_page(current_url)
        self.handle_response(current_url, response)  # handle reponse

        self._fetched.add(current_url)

        for i in range(self.concurrency):
          if self.urls:
            yield self._q.put(self.urls.pop())

      finally:
        self._q.task_done()

    @gen.coroutine
    def worker():
      while True:
        yield fetch_url()

    self._q.put(self.urls.pop())  # add first url

    # Start workers, then wait for the work queue to be empty.
    for _ in range(self.concurrency):
      worker()

    yield self._q.join(timeout=timedelta(seconds=300000))
    assert self._fetching == self._fetched

  def run(self):
    io_loop = ioloop.IOLoop.current()
    io_loop.run_sync(self._run)


class MySpider(AsySpider):

  def fetch(self, url, **kwargs):
    """重写父类fetch方法可以添加cookies,headers,timeout等信息"""
    cookies_str = "PHPSESSID=j1tt66a829idnms56ppb70jri4; pspt=%7B%22id%22%3A%2233153%22%2C%22pswd%22%3A%228835d2c1351d221b4ab016fbf9e8253f%22%2C%22_code%22%3A%22f779dcd011f4e2581c716d1e1b945861%22%7D; key=%E9%87%8D%E5%BA%86%E5%95%84%E6%9C%A8%E9%B8%9F%E7%BD%91%E7%BB%9C%E7%A7%91%E6%8A%80%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8; think_language=zh-cn; SERVERID=a66d7d08fa1c8b2e37dbdc6ffff82d9e|1444973193|1444967835; CNZZDATA1254842228=1433864393-1442810831-%7C1444972138"  # 从浏览器拷贝cookie字符串
    headers = {
      'User-Agent': 'mozilla/5.0 (compatible; baiduspider/2.0; +http://www.baidu.com/search/spider.html)',
      'cookie': cookies_str
    }
    return super(MySpider, self).fetch(  # 参数参考tornado文档
      url, headers=headers, request_timeout=1
    )

  def handle_html(self, url, html):
    print(url, html)


def main():
  urls = []
  for page in range(1, 100):
    urls.append('http://www.baidu.com?page=%s' % page)
  s = MySpider(urls)
  s.run()


if __name__ == '__main__':
  main()

能够世襲那一个类,塞一些url进去,然后重写handle_page管理得到的页面。

异步+多进度爬虫
还足以再格外点,加个进度池,使用了multiprocessing模块。功能飕飕的,

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import time
from multiprocessing import Pool
from datetime import timedelta
from tornado import httpclient, gen, ioloop, queues


class AsySpider(object):
  """A simple class of asynchronous spider."""
  def __init__(self, urls, concurrency):
    urls.reverse()
    self.urls = urls
    self.concurrency = concurrency
    self._q = queues.Queue()
    self._fetching = set()
    self._fetched = set()

  def handle_page(self, url, html):
    filename = url.rsplit('/', 1)[1]
    with open(filename, 'w+') as f:
      f.write(html)

  @gen.coroutine
  def get_page(self, url):
    try:
      response = yield httpclient.AsyncHTTPClient().fetch(url)
      print('######fetched %s' % url)
    except Exception as e:
      print('Exception: %s %s' % (e, url))
      raise gen.Return('')
    raise gen.Return(response.body)

  @gen.coroutine
  def _run(self):

    @gen.coroutine
    def fetch_url():
      current_url = yield self._q.get()
      try:
        if current_url in self._fetching:
          return

        print('fetching****** %s' % current_url)
        self._fetching.add(current_url)
        html = yield self.get_page(current_url)
        self._fetched.add(current_url)

        self.handle_page(current_url, html)

        for i in range(self.concurrency):
          if self.urls:
            yield self._q.put(self.urls.pop())

      finally:
        self._q.task_done()

    @gen.coroutine
    def worker():
      while True:
        yield fetch_url()

    self._q.put(self.urls.pop())

    # Start workers, then wait for the work queue to be empty.
    for _ in range(self.concurrency):
      worker()
    yield self._q.join(timeout=timedelta(seconds=300000))
    assert self._fetching == self._fetched

  def run(self):
    io_loop = ioloop.IOLoop.current()
    io_loop.run_sync(self._run)


def run_spider(beg, end):
  urls = []
  for page in range(beg, end):
    urls.append('http://127.0.0.1/%s.htm' % page)
  s = AsySpider(urls, 10)
  s.run()


def main():
  _st = time.time()
  p = Pool()
  all_num = 73000
  num = 4  # number of cpu cores
  per_num, left = divmod(all_num, num)
  s = range(0, all_num, per_num)
  res = []
  for i in range(len(s)-1):
    res.append((s[i], s[i+1]))
  res.append((s[len(s)-1], all_num))
  print res

  for i in res:
    p.apply_async(run_spider, args=(i[0], i[1],))
  p.close()
  p.join()

  print time.time()-_st


if __name__ == '__main__':
  main()

二十四线程爬虫
线程池达成.

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import Queue
import sys
import requests
import os
import threading
import time

class Worker(threading.Thread):  # 处理工作请求
  def __init__(self, workQueue, resultQueue, **kwds):
    threading.Thread.__init__(self, **kwds)
    self.setDaemon(True)
    self.workQueue = workQueue
    self.resultQueue = resultQueue


  def run(self):
    while 1:
      try:
        callable, args, kwds = self.workQueue.get(False)  # get task
        res = callable(*args, **kwds)
        self.resultQueue.put(res)  # put result
      except Queue.Empty:
        break

class WorkManager:  # 线程池管理,创建
  def __init__(self, num_of_workers=10):
    self.workQueue = Queue.Queue()  # 请求队列
    self.resultQueue = Queue.Queue()  # 输出结果的队列
    self.workers = []
    self._recruitThreads(num_of_workers)

  def _recruitThreads(self, num_of_workers):
    for i in range(num_of_workers):
      worker = Worker(self.workQueue, self.resultQueue)  # 创建工作线程
      self.workers.append(worker)  # 加入到线程队列


  def start(self):
    for w in self.workers:
      w.start()

  def wait_for_complete(self):
    while len(self.workers):
      worker = self.workers.pop()  # 从池中取出一个线程处理请求
      worker.join()
      if worker.isAlive() and not self.workQueue.empty():
        self.workers.append(worker)  # 重新加入线程池中
    print 'All jobs were complete.'


  def add_job(self, callable, *args, **kwds):
    self.workQueue.put((callable, args, kwds))  # 向工作队列中加入请求

  def get_result(self, *args, **kwds):
    return self.resultQueue.get(*args, **kwds)


def download_file(url):
  #print 'beg download', url
  requests.get(url).text


def main():
  try:
    num_of_threads = int(sys.argv[1])
  except:
    num_of_threads = 10
  _st = time.time()
  wm = WorkManager(num_of_threads)
  print num_of_threads
  urls = ['http://www.baidu.com'] * 1000
  for i in urls:
    wm.add_job(download_file, i)
  wm.start()
  wm.wait_for_complete()
  print time.time() - _st

if __name__ == '__main__':
  main()

那三种随意生龙活虎种都有极高的频率,不过如此跑会给网址服务器相当的大的压力,非常是小站点,仍然有点节操为好。

安装Tornado 省事点能够间接用grequests库,上边用的是tornado的异步client。
异步用到了…

Python完毕四线程抓取妹子图,python三十二线程

灵机一动写了个多线程抓妹子图,尽管代码仍有部分短处,不过依然记录下来,分享给我们。

Pic_downloader.py

# -*- coding: utf-8 -*-
"""
Created on Fri Aug 07 17:30:58 2015

@author: Dreace
"""
import urllib2
import sys
import time
import os
import random
from multiprocessing.dummy import Pool as ThreadPool 
type_ = sys.getfilesystemencoding()
def rename():
  return time.strftime("%Y%m%d%H%M%S")
def rename_2(name): 
  if len(name) == 2: 
    name = '0' + name + '.jpg' 
  elif len(name) == 1: 
    name = '00' + name + '.jpg' 
  else: 
    name = name + '.jpg' 
  return name
def download_pic(i):
  global count
  global time_out
  if Filter(i):
    try: 
      content = urllib2.urlopen(i,timeout = time_out)
      url_content = content.read()
      f = open(repr(random.randint(10000,999999999)) + "_" + rename_2(repr(count)),"wb")
      f.write(url_content)
      f.close()
      count += 1
    except Exception, e:
      print i + "下载超时,跳过!".decode("utf-8").encode(type_)
def Filter(content):
  for line in Filter_list:
    line=line.strip('\n')
    if content.find(line) == -1:
      return True
def get_pic(url_address):
  global pic_list
  try:
    str_ = urllib2.urlopen(url_address, timeout = time_out).read()
    url_content = str_.split("\"")
    for i in url_content:
      if i.find(".jpg") != -1:
        pic_list.append(i)  
  except Exception, e:
    print "获取图片超时,跳过!".decode("utf-8").encode(type_)
MAX = 2
count = 0
time_out = 60
thread_num = 30
pic_list = []
page_list = []
Filter_list = ["imgsize.ph.126.net","img.ph.126.net","img2.ph.126.net"]
dir_name = "C:\Photos\\"+rename()
os.makedirs(dir_name)
os.chdir(dir_name)
start_time = time.time()
url_address = "http://sexy.faceks.com/?page="
for i in range(1,MAX + 1): 
  page_list.append(url_address + repr(i))
page_pool = ThreadPool(thread_num)
page_pool.map(get_pic,page_list)
print "获取到".decode("utf-8").encode(type_),len(pic_list),"张图片,开始下载!".decode("utf-8").encode(type_)
pool = ThreadPool(thread_num) 
pool.map(download_pic,pic_list)
pool.close() 
pool.join()
print count,"张图片保存在".decode("utf-8").encode(type_) + dir_name
print "共耗时".decode("utf-8").encode(type_),time.time() - start_time,"s"

咱俩来看下三个网络朋友的著述

#coding: utf-8 #############################################################
# File Name: main.py
# Author: mylonly
# mail: [email protected]
# Created Time: Wed 11 Jun 2014 08:22:12 PM CST
#########################################################################
#!/usr/bin/python

import re,urllib2,HTMLParser,threading,Queue,time

#各图集入口链接
htmlDoorList = []
#包含图片的Hmtl链接
htmlUrlList = []
#图片Url链接Queue
imageUrlList = Queue.Queue(0)
#捕获图片数量
imageGetCount = 0
#已下载图片数量
imageDownloadCount = 0
#每个图集的起始地址,用于判断终止
nextHtmlUrl = ''
#本地保存路径
localSavePath = '/data/1920x1080/'

#如果你想下你需要的分辨率的,请修改replace_str,有如下分辨率可供选择1920x1200,1980x1920,1680x1050,1600x900,1440x900,1366x768,1280x1024,1024x768,1280x800
replace_str = '1920x1080'

replaced_str = '960x600'

#内页分析处理类
class ImageHtmlParser(HTMLParser.HTMLParser):
def __init__(self):
self.nextUrl = ''
HTMLParser.HTMLParser.__init__(self)
def handle_starttag(self,tag,attrs):
global imageUrlList
if(tag == 'img' and len(attrs) > 2 ):
if(attrs[0] == ('id','bigImg')):
url = attrs[1][1]
url = url.replace(replaced_str,replace_str)
imageUrlList.put(url)
global imageGetCount
imageGetCount = imageGetCount + 1
print url
elif(tag == 'a' and len(attrs) == 4):
if(attrs[0] == ('id','pageNext') and attrs[1] == ('class','next')):
global nextHtmlUrl
nextHtmlUrl = attrs[2][1];

#首页分析类
class IndexHtmlParser(HTMLParser.HTMLParser):
def __init__(self):
self.urlList = []
self.index = 0
self.nextUrl = ''
self.tagList = ['li','a']
self.classList = ['photo-list-padding','pic']
HTMLParser.HTMLParser.__init__(self)
def handle_starttag(self,tag,attrs):
if(tag == self.tagList[self.index]):
for attr in attrs:
if (attr[1] == self.classList[self.index]):
if(self.index == 0):
#第一层找到了
self.index = 1
else:
#第二层找到了
self.index = 0
print attrs[1][1]
self.urlList.append(attrs[1][1])
break
elif(tag == 'a'):
for attr in attrs:
if (attr[0] == 'id' and attr[1] == 'pageNext'):
self.nextUrl = attrs[1][1]
print 'nextUrl:',self.nextUrl
break

#首页Hmtl解析器
indexParser = IndexHtmlParser()
#内页Html解析器
imageParser = ImageHtmlParser()

#根据首页得到所有入口链接
print '开始扫描首页...'
host = 'http://desk.zol.com.cn'
indexUrl = '/meinv/'
while (indexUrl != ''):
print '正在抓取网页:',host+indexUrl
request = urllib2.Request(host+indexUrl)
try:
m = urllib2.urlopen(request)
con = m.read()
indexParser.feed(con)
if (indexUrl == indexParser.nextUrl):
break
else:
indexUrl = indexParser.nextUrl
except urllib2.URLError,e:
print e.reason

print '首页扫描完成,所有图集链接已获得:'
htmlDoorList = indexParser.urlList

#根据入口链接得到所有图片的url
class getImageUrl(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
for door in htmlDoorList:
print '开始获取图片地址,入口地址为:',door
global nextHtmlUrl
nextHtmlUrl = ''
while(door != ''):
print '开始从网页%s获取图片...'% (host+door)
if(nextHtmlUrl != ''):
request = urllib2.Request(host+nextHtmlUrl)
else:
request = urllib2.Request(host+door)
try:
m = urllib2.urlopen(request)
con = m.read()
imageParser.feed(con)
print '下一个页面地址为:',nextHtmlUrl
if(door == nextHtmlUrl):
break
except urllib2.URLError,e:
print e.reason
print '所有图片地址均已获得:',imageUrlList

class getImage(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global imageUrlList
print '开始下载图片...'
while(True):
print '目前捕获图片数量:',imageGetCount
print '已下载图片数量:',imageDownloadCount
image = imageUrlList.get()
print '下载文件路径:',image
try:
cont = urllib2.urlopen(image).read()
patter = '[0-9]*\.jpg';
match = re.search(patter,image);
if match:
print '正在下载文件:',match.group()
filename = localSavePath+match.group()
f = open(filename,'wb')
f.write(cont)
f.close()
global imageDownloadCount
imageDownloadCount = imageDownloadCount + 1
else:
print 'no match'
if(imageUrlList.empty()):
break
except urllib2.URLError,e:
print e.reason
print '文件全部下载完成...'

get = getImageUrl()
get.start()
print '获取图片链接线程启动:'

time.sleep(2)

download = getImage()
download.start()
print '下载图片链接线程启动:'

批量抓取内定网页上的全体图片

# -*- coding:utf-8 -*-
# coding=UTF-8

import os,urllib,urllib2,re

url = u"http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=index&fr=&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=python&oq=python&rsp=-1"
outpath = "t:\\"

def getHtml(url):
  webfile = urllib.urlopen(url)
  outhtml = webfile.read()
  print outhtml
  return outhtml

def getImageList(html):
  restr=ur'('
  restr+=ur'http:\/\/[^\s,"]*\.jpg'
  restr+=ur'|http:\/\/[^\s,"]*\.jpeg'
  restr+=ur'|http:\/\/[^\s,"]*\.png'
  restr+=ur'|http:\/\/[^\s,"]*\.gif'
  restr+=ur'|http:\/\/[^\s,"]*\.bmp'
  restr+=ur'|https:\/\/[^\s,"]*\.jpeg'  
  restr+=ur'|https:\/\/[^\s,"]*\.jpeg'
  restr+=ur'|https:\/\/[^\s,"]*\.png'
  restr+=ur'|https:\/\/[^\s,"]*\.gif'
  restr+=ur'|https:\/\/[^\s,"]*\.bmp'
  restr+=ur')'
  htmlurl = re.compile(restr)
  imgList = re.findall(htmlurl,html)
  print imgList
  return imgList

def download(imgList, page):
  x = 1
  for imgurl in imgList:
    filepathname=str(outpath+'pic_%09d_%010d'%(page,x)+str(os.path.splitext(urllib2.unquote(imgurl).decode('utf8').split('/')[-1])[1])).lower()
    print '[Debug] Download file :'+ imgurl+' >> '+filepathname
    urllib.urlretrieve(imgurl,filepathname)
    x+=1

def downImageNum(pagenum):
  page = 1
  pageNumber = pagenum
  while(page <= pageNumber):
    html = getHtml(url)#获得url指向的html内容
    imageList = getImageList(html)#获得所有图片的地址,返回列表
    download(imageList,page)#下载所有的图片
    page = page+1

if __name__ == '__main__':
  downImageNum(1)

上述正是给大家聚集的3款Python完毕的批量抓取妹纸图片的代码了,希望对大家学习Python爬虫能够具备助于。

灵机一动写了个四线程抓妹子图,尽管代码照旧有意气风发对顽疾,可是依旧记录下来,分享给我们。…

Python四十多线程和Python的锁,python八线程

Python多线程 
Python中落实六十二线程有二种方法,生机勃勃种基于_thread模块(在Python2.x版本中为thread模块,未有下划线)的start_new_thread()函数,另意气风发种基于threading模块的Thread类。 
事实上Python的四十多线程编制程序不可能真的使用多核的CPU,可是用开源模块使您的测算压力遍及到多核CPU上……… 

一.使用start_new_thread()完结线程,是比较底层的贯彻格局,全体线程分享他们global数据,为了达到同盟,模块也提供了简约的锁机制 

_thread.start_new_thread(function, args[, kwargs])
启动一个新的进程,并返回其标识符. 线程执行的函数需要的参数由args(必须为一个元组)提供,亦可通过可选参数kwargs提供关键字参数组  成的字典。当函数返回时,启动的线程也   停止退出。如果函数中存在未处理异常,会打印堆栈跟踪后线程停止退出(其他线程继续执行)。

里头线程标记符是一个非0整数,并未从来意思,能够看做从八个线程组成的奇特字典中索引本线程的一个key,也可用_thread.get_ident()得到,在线程退出后,标志符会被系统回笼。在线程推行进程中能够调用_thread.exit()终止本线程的进行。 

Java代码  澳门威斯尼人平台登陆 1

  1. import _thread  
  2. import time  
  3. def threadFunction(count):  
  4.     for i in range(count):  
  5.       print(‘进程id为%d的打印%d’%(_thread.get_ident(),i))  
  6.       i-=1  
  7.       time.sleep(0.1)  
  8.   
  9. def begin():  
  10.   ident1=_thread.start_new_thread(threadFunction,(100,))  
  11.   print(‘运转标志符为%d的历程’%(ident1,))  
  12.   ident2=_thread.start_new_thread(threadFunction,(100,))  
  13.   print(‘运行标记符为%d的进度’%(ident2,))  
  14.   
  15.    
  16. if __name__ == ‘__main__’:  
  17.   begin()  

二.接收Thread类来促成三十四线程,这种方法是对_thread模块(若无_thread,则为dummy_threading)的高等封装,在这里种措施下大家需创立新类世襲threading.Thread,和java同样重写threading.Thread的run方法就能够.运维线程用线程的start方法,它会调用大家重写的run方法. 

Java代码  澳门威斯尼人平台登陆 2

  1. class MyThread(threading.Thread):  
  2.     ”’只好重写__init__ 和 run 三个章程”’  
  3.     def __init__(self,name):  
  4.         threading.Thread.__init__(self)  
  5.         self.name=name  
  6.         self.bool_stop=False  
  7.     def run(self):  
  8.         while not self.bool_stop:  
  9.             print(‘进程%s,于%s’%(self.name,time.asctime()))  
  10.             time.sleep(1)  
  11.     def stop(self):  
  12.         self.bool_stop = True  
  13.   
  14.   
  15. if __name__ == ‘__main__’:  
  16.     th1=MyThread(‘one’)  
  17.     th2=MyThread(‘two’)  
  18.     th1.start()  
  19.     th2.start()  

Thread类还定义了以下常用方法与品质: 

Thread.getName() \Thread.setName()
老方式用于获取和设置线程的名称,官方建议用Thread.name替代
Thread.ident
获取线程的标识符。只有在调用start()方法执行后才有效,否则返回None。
Thread.is_alive()
判断线程是否是激活的。
Thread.join([timeout])
调用Thread.join将会使主调线程堵塞,直到被调用线程运行结束或超时。参数timeout是一个数值类型,表示超时时间,如果未提供该参数,那么主调线程将一直堵塞到被调线程结束。

Python中的锁 

先用_thread模块的Lock锁来贯彻临盆者花费者难题,Lock对象是Python提供的低档线程序调控制工具,使用起来极其轻松,只需上面3条语句就可以: 

_thread.allocate_lock()返回一个新Lock对象,即为一个新锁
lock.acquire() 相当于P操作,得到一个锁,
lock.release()相当于V操作,释放一个锁

代码如下: 

Java代码  澳门威斯尼人平台登陆 3

  1. import _thread,time,random  
  2. dish=0  
  3. lock = _thread.allocate_lock()  
  4. def producerFunction():  
  5.    ”’如若投的筛子比0.2大,则向盘子中追加叁个苹果”’  
  6.    global lock,dish  
  7.    while True:  
  8.        if(random.random() > 0.1):  
  9.          lock.acquire()  
  10.          if dish < 100:  
  11.            dish+=1  
  12.            print(‘分娩者扩大了贰个苹果,今后有%d个苹果’%(dish,))  
  13.          lock.release()  
  14.          time.sleep(random.random()*3)  
  15.   
  16. def consumerFunction():  
  17.   ”’假如投的筛子比0.5大,则从市价中取三个苹果”’  
  18.   global lock,dish  
  19.   while True:  
  20.     if(random.random() > 0.9):  
  21.       lock.acquire()  
  22.       if dish > 0:  
  23.         dish-=1  
  24.         print(‘花销者拿走三个苹果现,在有%d个苹果’%(dish,))  
  25.       lock.release()  
  26.       time.sleep(random.random()*3)  
  27.   
  28. def begin():  
  29.   ident1=_thread.start_new_thread(producerFunction,())  
  30.   ident2=_thread.start_new_thread(consumerFunction,())   
  31. if __name__ == ‘__main__’:  
  32.   begin()  

另多少个较高等的锁为翼虎Lock锁,奥迪Q7Lock对象内部维护着叁个Lock对象,它是黄金时代种可重入的靶子。对于Lock对象来说,假若三个线程接二连三三回进行acquire操作,那么由于第一回acquire之后并未有release,第2回acquire将挂起线程。那会变成Lock对象长久不会release,使得线程死锁。ENVISIONLock对象允许多少个线程数十次对其进展acquire操作,因为在其内部通过七个counter变量维护着线程acquire的次数。况且每贰次的acquire操作必需有一个release操作与之相应,在颇有的release操作完结之后,其余线程工夫申请该库罗德Lock对象。 

threading模块对Lock也提供和包裹,提供了更加尖端的一齐方式(能够精晓为越来越高端的锁卡塔尔国,富含threading.Event和threading.Condition,个中threading.伊芙nt为提供了简易的多只方式:三个经过标识event,其余进程等待,只需下边包车型大巴多少个章程就能够: 

Event.wait([timeout])
堵塞线程,直到Event对象内部标识位被设为True或超时(如果提供了参数timeout)。
Event.set()
将标识号设为Ture
Event.clear()
设为标识符False

threading.Condition 能够把Condiftion驾驭为风流罗曼蒂克把高等的琐,它提供了比Lock,
冠道Lock更加尖端的功能,允许大家能够决定复杂的线程同步难题。threadiong.Condition在其间维护多个琐对象(暗中认可是QX56Lock卡塔尔,能够在开创Condigtion对象的时候把琐对象作为参数传入。Condition也提供了acquire,
release方法,其含义与琐的acquire,
release方法豆蔻梢头致,其实它只是简单的调用内部琐对象的对应的办法而已。Condition还提供了之类方法(非常要小心:那几个点子独有在挤占琐(acquire)之后技艺调用,不然将会报RuntimeError非常。): 

Condition.wait([timeout]):    
wait方法释放内部所占用的琐,同时线程被挂起,直至接收到通知被唤醒或超时(如果提供了timeout参数的话)。当线程被唤醒并重新占有琐的时候,程序才会继续执行下去。
Condition.notify():  
唤醒一个挂起的线程(如果存在挂起的线程)。注意:notify()方法不会释放所占用的琐。
Condition.notify_all()
唤醒所有挂起的线程(如果存在挂起的线程)。注意:这些方法不会释放所占用的琐。

Python代码的奉行由Python设想机(解释器卡塔 尔(阿拉伯语:قطر‎来调控。

上面这段python的八线程代码为什么运转不起来,说是函数未有加锁的质量

上面包车型大巴代码能够,因为你丰富lock是变量又是函数,会冲突的,别的,你这几个试验其实地度量试不出去lock属性,因为您调用实际上是逐意气风发的

import string,socket,time,os,sys,threading
num=0
class xThread():
def __init__(self):
self._lock=threading.Lock()
def lock(self):
self._lock.acquire()
def unlock(self):
self._lock.release()

def p2(a):
global num
thread.lock()
num+=1
print(a+str(num))
time.sleep(0.1)
thread.unlock()

def p1(a):
for i in range(3):
info=’this %s thread’%(i)
p2(info)

def main():
for i in range(3):
p1(i)

if __name__ == ‘__main__’:
thread=xThread()
main()
 

Python在安排之初就思谋要在主循环中,同临时候独有一个线程在举行,

python十二线程 能够不得以查看锁的个数

给lock加个变量保存锁的层数吧,每acquire一遍就加1,每release叁回就减1,也就不用别的找哪些函数了。
 

Python多线程Python中贯彻四线程有三种情势,风姿洒脱种基于_thread模块(在Python2.x本子中为thread模块,没有下划…

就如单CPU的系统中运作多个经过那样,内部存款和储蓄器中得以存放八个程序,

但随意时刻,唯有一个主次在CPU中运营。

相通地,就算Python解释器能够运作多少个线程,唯有三个线程在解释器中运营。

 

对Python设想机的访谈由全局解释器锁(GIL卡塔尔国来调整,正是以此锁能保障同偶然间独有八个线程在运行。在三十四线程境遇中,Python设想机遵照以下方法进行。

1.设置GIL。

2.切换成一个线程去实施。

3.运行。

4.把线程设置为睡眠状态。

5.解锁GIL。

6.重新重复以上步骤。

 python
每实行玖十多个字节码,GIL锁就能够解锁贰遍,让别的线程实践,所以,python五十多线程遭逢,是交替实施,上下文切换,并从未相同时刻执行代码.

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图