您的位置:首页 > 编程语言 > Python开发

Python多线程抓取图片

2014-07-01 10:10 543 查看

1、基础知识

利用Python的urllib和urllib2库访问并下载网页

1.1、访问某个网址并打印

import urllib2

url = 'http://www.baidu.com'
respone = urllib2.urlopen(url)
page = respone.read()
print page



1.2、将网页保存至文件

import urllib

url = 'http://www.baidu.com'
fname = '1.html'
urllib.urlretrieve(url,fname)


1.3、伪装浏览器

某些网站拒绝爬虫的访问,此时需要将爬虫伪装成浏览器,可通过修改http包的header实现。

url = 'http://m.qiushibaike.com'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = { 'User-Agent' : user_agent }
req = urllib2.Request(url, headers = headers)
response = urllib2.urlopen(req)


1.4、文件系统操作

从网络上爬下来的资源需要保存在本地,这时需要对文件系统进行操作。判断保存的路径是否存在,若不存在则创建。

import os
fileName = 'D:/123'
if not os.path.exists(fileName):
os.makedirs(fileName)


1.5、时间函数

每次测试或者爬取资源通常会选择不同的系统路径,每次都手动修改有点不科学,因此可选择用系统时间作为文件名。

t = time.localtime()
folderName = 'D:/TuChong/' + str(t.__getattribute__('tm_year')) + '-' + str(t.__getattribute__('tm_mon')) + '-' + str(t.__getattribute__('tm_mday')) + '-' + str(self.pageNo) +'/'


1.6、正则表达式

访问网页后,自动选择爬取哪些资源是爬虫设计的关键。从网页众多的内容中抠出你需要的资源,需要使用正则表达式,详细介绍可看:Python正则表达式指南

2、线程

Python的线程有两个基本的函数,__init__()和run()。其中__init__()负责线程的初始化,run()负责主要任务的执行。线程通过start()函数启动。

我们可以通过继承的方式建立自己的线程。

from threading import Thread

class CatchLinks(Thread):
def __init__(self):
pass

def run(self):
pass


本文的爬虫,根据用户输入的起始页数和终止页数,下载页数范围内的所有图片。

因此,每一页可以启动一个线程,负责提取本文内所有帖子的url。

然后,对于页内的每一个帖子,启动一个线程负责下载帖内的所有图片。

所以,本文定义了两种类型的线程,CatchLinks和CatchImages。

3、源代码

# coding=utf-8

# ----------------------------------
# Python多线程抓取图片
# data:2014.6.27
# author:XuZekun
# version:2.0
# ----------------------------------

import urllib2
import re
import string
import urllib
from threading import Thread
import time
import os

class CatchLinks(Thread):
url = None
keepRunning = False	#状态标识
subThreads = []
pageNo = None

def __init__(self,url,pageNo):
Thread.__init__(self)
self.url = url
self.keepRunning = True
self.pageNo = pageNo

# 获取当前页面所有图片主题的二级链接
def getLinks(self):
try:
respone = urllib2.urlopen(self.url)
mainPage = respone.read()
except:
print 'Get MainPage failed!'

links =  re.findall('class="theatre-view" href="(.*?)" title="(.*?)">',mainPage,re.S)
return links

#获取子链接下所有图片的url,并下载保存
def getImgs(self,links):
for item in links:
if self.keepRunning == True:
print item[0]
#print item[1]
title = item[1].decode("utf-8").replace('/','').replace("'",'')
print title
t = CatchImages(item[0],title,self.pageNo)
t.start()
self.subThreads.append(t)

def run(self):
links = self.getLinks()
self.getImgs(links)

def quitThreads(self):
for subThread in self.subThreads:
subThread.keepRunning = False
print 'subThread quit'

class CatchImages(Thread):
url = None
keepRunning = False
title = None
pageNo = None

def __init__(self,url,title,pageNo):
Thread.__init__(self)
self.url = url
self.title = title
self.keepRunning = True
self.pageNo = pageNo

def getImgs(self,link,title):
try:
subPageRespone = urllib2.urlopen(link)
subPage = subPageRespone.read()
print 'subThread start'
except:
print 'Get subPage:' + title + 'failed!'

imgurls = re.findall('<figure style=.*?<img src="(.*?)" class="img-responsive copyright-contextmenu"',subPage,re.S)

t = time.localtime()
folderName = 'D:/TuChong/' + str(t.__getattribute__('tm_year')) + '-' + str(t.__getattribute__('tm_mon')) + '-' \
+ str(t.__getattribute__('tm_mday')) + '-' + str(self.pageNo) +'/'
if not os.path.exists(folderName):
os.makedirs(folderName)

for i in range(len(imgurls)):
if self.keepRunning == True:
fname = folderName + title + str(i) + '.jpg'	#图片保存路径
try:
urllib.urlretrieve(imgurls[i],fname)
except:
print 'write file ' + title + ' error'
print imgurls[i]

def run(self):
self.getImgs(self.url,self.title)

def quit(threads,startPage):
for i in range(len(threads)):
threads[i].quitThreads()
threads[i].keepRunning = False
print 'thread %d quit' %(i + startPage)
print 'exit'

if __name__ == '__main__':
url = 'http://tuchong.com/tags/%E4%BA%BA%E5%83%8F?page='
threads = []
startPage = 8
endPage = 9

for i in range(startPage,endPage+1):	#每一页发起一个线程
print 'thread %d start' %i
t = CatchLinks(url + str(i),i)
t.start()
threads.append(t)

while True:
cmd = raw_input()
if cmd =='quit':
quit(threads,startPage)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: