Python使用代理抓取网站图片(多线程)


Posted in Python onMarch 14, 2014

一、功能说明:
1. 多线程方式抓取代理服务器,并多线程验证代理服务器
ps 代理服务器是从http://www.cnproxy.com/ (测试只选择了8个页面)抓取
2. 抓取一个网站的图片地址,多线程随机取一个代理服务器下载图片
二、实现代码

#!/usr/bin/env python
#coding:utf-8
import urllib2
import re
import threading
import time
import random
rawProxyList = []
checkedProxyList = []
imgurl_list = []
#抓取代理网站
portdicts ={'v':"3",'m':"4",'a':"2",'l':"9",'q':"0",'b':"5",'i':"7",'w':"6",'r':"8",'c':"1"}
targets = []
for i in xrange(1,9):
        target = r"http://www.cnproxy.com/proxy%d.html" % i
        targets.append(target)
#print targets
#抓取代理服务器正则
p = re.compile(r'''<tr><td>(.+?)<SCRIPT type=text/javascript>document.write\(":"\+(.+?)\)</SCRIPT></td><td>(.+?)</td><td>.+?</td><td>(.+?)</td></tr>''')
#获取代理的类
class ProxyGet(threading.Thread):
    def __init__(self,target):
        threading.Thread.__init__(self)
        self.target = target
    def getProxy(self):
        print "代理服务器目标网站: " + self.target
        req = urllib2.urlopen(self.target)
        result = req.read()
        #print chardet.detect(result)
        matchs = p.findall(result)
        for row in matchs:
            ip=row[0]
            port =row[1]
            port = map(lambda x:portdicts[x],port.split('+'))
            port = ''.join(port)
            agent = row[2]
            addr = row[3].decode("cp936").encode("utf-8")
            proxy = [ip,port,addr]
            #print proxy
            rawProxyList.append(proxy)
    def run(self):
        self.getProxy()
#检验代理的类
class ProxyCheck(threading.Thread):
    def __init__(self,proxyList):
        threading.Thread.__init__(self)
        self.proxyList = proxyList
        self.timeout = 5
        self.testUrl = "http://www.baidu.com/"
        self.testStr = "030173"
    def checkProxy(self):
        cookies = urllib2.HTTPCookieProcessor()
        for proxy in self.proxyList:
            proxyHandler = urllib2.ProxyHandler({"http" : r'http://%s:%s' %(proxy[0],proxy[1])})
            #print r'http://%s:%s' %(proxy[0],proxy[1])
            opener = urllib2.build_opener(cookies,proxyHandler)
            opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0')] 
            #urllib2.install_opener(opener)
            t1 = time.time()
            try:
                #req = urllib2.urlopen("http://www.baidu.com", timeout=self.timeout)
                req = opener.open(self.testUrl, timeout=self.timeout)
                #print "urlopen is ok...."
                result = req.read()
                #print "read html...."
                timeused = time.time() - t1
                pos = result.find(self.testStr)
                #print "pos is %s" %pos
                if pos > 1:
                    checkedProxyList.append((proxy[0],proxy[1],proxy[2],timeused))
                    #print "ok ip: %s %s %s %s" %(proxy[0],proxy[1],proxy[2],timeused)
                else:
                     continue
            except Exception,e:
                #print e.message
                continue
    def run(self):
        self.checkProxy()
#获取图片地址函数
def imgurlList(url_home):
    global imgurl_list
    home_page = urllib2.urlopen(url_home)
    url_re = re.compile(r'<li><a href="(.+?)" target="_blank" rel="nofollow">')
    pic_re = re.compile(r'<img src="(.*?\.\w{3,4})"')
    url_list = re.findall(url_re,home_page.read())
    for url in url_list:
        #print url_home+url
        url_page = urllib2.urlopen(url_home+url)
        for imgurlList in re.findall(pic_re,url_page.read()):
            imgurl_list.append(imgurlList)
#下载图片的类
class getPic(threading.Thread):
    def __init__(self,imgurl_list):
        threading.Thread.__init__(self)
        self.imgurl_list = imgurl_list 
        self.timeout = 5
    def downloadimg(self):
        for imgurl in self.imgurl_list:
            pic_suffix = imgurl.split('.')[-1] #获取图片后缀
            pic_name = str(random.randint(0,10000000000))+'.'+pic_suffix
            cookies = urllib2.HTTPCookieProcessor()
            randomCheckedProxy = random.choice(checkedProxyList) #随机取一组代理服务器
            proxyHandler = urllib2.ProxyHandler({"http" : r'http://%s:%s' %(randomCheckedProxy[0],randomCheckedProxy[1])})
            opener = urllib2.build_opener(cookies,proxyHandler)
            opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0')]
            urllib2.install_opener(opener)
            try:
                data_img = opener.open(imgurl,timeout=self.timeout)
                f = open (pic_name,'wb')
                f.write(data_img.read())
                f.close()
            except:
                continue
    def run(self):
        self.downloadimg()
if __name__ == "__main__":
    getThreads = []
    checkThreads = []
    imgurlList('http://www.ivsky.com')
    getPicThreads = []
#对每个目标网站开启一个线程负责抓取代理
for i in range(len(targets)):
    t = ProxyGet(targets[i])
    getThreads.append(t)
for i in range(len(getThreads)):
    getThreads[i].start()
for i in range(len(getThreads)):
    getThreads[i].join()
print '.'*10+"总共抓取了%s个代理" %len(rawProxyList) +'.'*10
#开启20个线程负责校验,将抓取到的代理分成20份,每个线程校验一份
for i in range(20):
    t = ProxyCheck(rawProxyList[((len(rawProxyList)+19)/20) * i:((len(rawProxyList)+19)/20) * (i+1)])
    checkThreads.append(t)
for i in range(len(checkThreads)):
    checkThreads[i].start()
for i in range(len(checkThreads)):
    checkThreads[i].join()
print '.'*10+"总共有%s个代理通过校验" %len(checkedProxyList) +'.'*10
#开启20个线程随机取一个代理下载图片
for i in range(20):
    t = getPic(imgurl_list[((len(imgurl_list)+19)/20) * i:((len(imgurl_list)+19)/20) * (i+1)])
    getPicThreads.append(t)
for i in range(len(getPicThreads)):
    getPicThreads[i].start()
for i in range(len(getPicThreads)):
    getPicThreads[i].join()
print '.'*10+"总共有%s个图片下载" %len(imgurl_list) +'.'*10
#代理排序持久化
f= open("proxy_list.txt",'w+')
for proxy in sorted(checkedProxyList,cmp=lambda x,y:cmp(x[3],y[3])):
    #print "checked proxy is: %s:%s\t%s\t%s" %(proxy[0],proxy[1],proxy[2],proxy[3])
    f.write("%s:%s\t%s\t%s\n"%(proxy[0],proxy[1],proxy[2],proxy[3]))
f.close()

二、测试结果:

# ls
proxy_getpic.py
# python proxy_getpic.py
代理服务器目标网站: http://www.cnproxy.com/proxy1.html
代理服务器目标网站: http://www.cnproxy.com/proxy2.html
代理服务器目标网站: http://www.cnproxy.com/proxy3.html
代理服务器目标网站: http://www.cnproxy.com/proxy4.html
代理服务器目标网站: http://www.cnproxy.com/proxy5.html
代理服务器目标网站: http://www.cnproxy.com/proxy6.html
代理服务器目标网站: http://www.cnproxy.com/proxy7.html
代理服务器目标网站: http://www.cnproxy.com/proxy8.html
..........总共抓取了800个代理..........
..........总共有458个代理通过校验..........
..........总共有154个图片下载..........
# cat proxy_list.txt | more
173.213.113.111:3128    United States   0.432188987732
173.213.113.111:8089    United States   0.441318035126
173.213.113.111:7808    United States   0.444597005844
110.4.24.170:80 香港 香港移动通讯有限公司       0.489440202713
211.142.236.135:8080    湖南省株洲市 移动       0.490673780441
211.142.236.135:8081    湖南省株洲市 移动       0.518096923828
211.142.236.135:8000    湖南省株洲市 移动       0.51860499382
211.142.236.135:8082    湖南省株洲市 移动       0.520448207855
# ls
1001117689.jpg  3097883176.jpg  5234319709.jpg  7012274766.jpg  8504924248.jpg
1076458640.jpg  3144369522.jpg  5387877704.jpg  7106183143.jpg  867723868.jpg
1198548712.jpg  3161307031.jpg  5572092752.jpg  7361254661.jpg  8746315373.jpg
165738192.jpg   3228008315.jpg  5575388077.jpg  7389537793.jpg  8848973192.jpg
1704512138.jpg  3306931164.jpg  5610740708.jpg  7407358698.jpg  8973834958.jpg
1742167711.jpg  3320152673.jpg  5717429022.jpg  7561176207.jpg  8976862152.jpg
...............
Python 相关文章推荐
Ubuntu 14.04+Django 1.7.1+Nginx+uwsgi部署教程
Nov 18 Python
Python中用Spark模块的使用教程
Apr 13 Python
Python中设置变量访问权限的方法
Apr 27 Python
Python实现比较两个列表(list)范围
Jun 12 Python
python中学习K-Means和图片压缩
Nov 20 Python
python使用jieba实现中文分词去停用词方法示例
Mar 11 Python
一条命令解决mac版本python IDLE不能输入中文问题
May 15 Python
python MNIST手写识别数据调用API的方法
Aug 08 Python
Python使用folium excel绘制point
Jan 03 Python
Django框架基础模板标签与filter使用方法详解
Jul 23 Python
python处理excel绘制雷达图
Oct 18 Python
Python读取xlsx数据生成图标代码实例
Aug 12 Python
python3.3使用tkinter开发猜数字游戏示例
Mar 14 #Python
Python subprocess模块学习总结
Mar 13 #Python
用Python和MD5实现网站挂马检测程序
Mar 13 #Python
python操作数据库之sqlite3打开数据库、删除、修改示例
Mar 13 #Python
使用Python判断IP地址合法性的方法实例
Mar 13 #Python
Python 分析Nginx访问日志并保存到MySQL数据库实例
Mar 13 #Python
详解Python中的__init__和__new__
Mar 12 #Python
You might like
Apache中php.ini的设置方法
2013/02/28 PHP
php获取excel文件数据
2017/04/21 PHP
PHP文件系统管理(实例讲解)
2017/09/19 PHP
PHP智能识别收货地址信息实例
2019/01/05 PHP
实例介绍PHP删除数组中的重复元素
2019/03/03 PHP
为JavaScript提供睡眠功能(sleep) 自编译JS引擎
2010/08/16 Javascript
浅谈JavaScript编程语言的编码规范
2011/10/21 Javascript
Jquery刷新页面背景图片随机变换的实现方法
2013/03/15 Javascript
浏览器窗口大小变化时使用resize事件对框架不起作用的解决方法
2014/05/11 Javascript
简介JavaScript中fixed()方法的使用
2015/06/08 Javascript
JavaScript中函数表达式和函数声明及函数声明与函数表达式的不同
2015/11/15 Javascript
关于原生js中bind函数的简单实现
2016/08/10 Javascript
微信小程序 密码输入(源码下载)
2017/06/27 Javascript
微信小程序组件之srcoll-view的详解
2017/10/19 Javascript
Vue.js项目中管理每个页面的头部标签的两种方法
2018/06/25 Javascript
js中的面向对象之对象常见创建方法详解
2019/12/16 Javascript
python模拟登录百度贴吧(百度贴吧登录)实例
2013/12/18 Python
Python3之文件读写操作的实例讲解
2018/01/23 Python
python如何实现int函数的方法示例
2018/02/19 Python
对python 多个分隔符split 的实例详解
2018/12/20 Python
快速解决pyqt5窗体关闭后子线程不同时退出的问题
2019/06/19 Python
Django 解决distinct无法去除重复数据的问题
2020/05/20 Python
python如何利用Mitmproxy抓包
2020/10/10 Python
python tkinter实现下载进度条及抖音视频去水印原理
2021/02/07 Python
CSS3动画:5种预载动画效果实例
2017/04/05 HTML / CSS
HTML5中的Web Notification桌面右下角通知功能的实现
2018/04/19 HTML / CSS
Melissa香港官网:MDreams
2016/07/01 全球购物
介绍一下sql server的安全性
2014/08/10 面试题
岳父生日宴会答谢词
2014/01/13 职场文书
普罗米修斯教学反思
2014/02/06 职场文书
应届大学生求职信
2014/07/20 职场文书
三峡大坝导游词
2015/01/31 职场文书
2015年教务工作总结
2015/05/23 职场文书
CSS实现两列布局的N种方法
2021/08/02 HTML / CSS
CSS三大特性继承性、层叠性和优先级详解
2022/01/18 HTML / CSS
vue使用refs获取嵌套组件中的值过程
2022/03/31 Vue.js