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 相关文章推荐
Python元组及文件核心对象类型详解
Feb 11 Python
Linux下python与C++使用dlib实现人脸检测
Jun 29 Python
Python数据分析matplotlib设置多个子图的间距方法
Aug 03 Python
python斐波那契数列的计算方法
Sep 27 Python
对Python3.x版本print函数左右对齐详解
Dec 22 Python
Python企业编码生成系统总体系统设计概述
Jul 26 Python
python list数据等间隔抽取并新建list存储的例子
Nov 27 Python
Python线程障碍对象Barrier原理详解
Dec 02 Python
三个python爬虫项目实例代码
Dec 28 Python
详解Python修复遥感影像条带的两种方式
Feb 23 Python
python 利用zmail库发送邮件
Sep 11 Python
OpenCV绘制圆端矩形的示例代码
Aug 30 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
实时抓取YAHOO股票报价的代码
2006/10/09 PHP
一步一步学习PHP(8) php 数组
2010/03/05 PHP
PHP回溯法解决0-1背包问题实例分析
2015/03/23 PHP
wordpress安装过程中遇到中文乱码的处理方法
2015/04/21 PHP
PDO操作MySQL的基础教程(推荐)
2017/08/18 PHP
ThinkPHP5 验证器的具体使用
2018/05/31 PHP
Jquery刷新页面背景图片随机变换的实现方法
2013/03/15 Javascript
关于JQuery($.load)事件的用法和分析
2013/04/09 Javascript
js中typeof的用法汇总
2013/12/12 Javascript
js读取json的两种常用方法示例介绍
2014/10/19 Javascript
javascript获取四位数字或者字母的随机数
2015/01/09 Javascript
JavaScript常用脚本汇总(一)
2015/03/04 Javascript
几种二级联动案例(jQuery\Array\Ajax php)
2016/08/13 Javascript
require、backbone等重构手机图片查看器
2016/11/17 Javascript
利用JS实现简单的日期选择插件
2017/01/23 Javascript
微信小程序 出现错误:{&quot;baseresponse&quot;:{&quot;errcode&quot;:-80002,&quot;errmsg&quot;:&quot;&quot;}}解决办法
2017/02/23 Javascript
JavaScript 获取元素在父节点中的下标(推荐)
2017/06/28 Javascript
Vue异步加载about组件
2017/10/31 Javascript
浅析Node.js非对称加密方法
2018/01/29 Javascript
AngularJS 事件发布机制
2018/08/28 Javascript
jQuery实现每日秒杀商品倒计时功能
2019/09/06 jQuery
[01:16:16]DOTA2-DPC中国联赛定级赛 RNG vs Phoenix BO3第二场 1月8日
2021/03/11 DOTA
python进阶教程之文本文件的读取和写入
2014/08/29 Python
python脚本设置系统时间的两种方法
2016/02/21 Python
浅析Python中的多条件排序实现
2016/06/07 Python
TensorFlow如何实现反向传播
2018/02/06 Python
Python正则表达式匹配数字和小数的方法
2019/07/03 Python
HTML5 HTMLCollection和NodeList的区别详解
2020/04/29 HTML / CSS
HttpServlet类中的主要方法都有哪些?各自的作用是什么?
2014/03/16 面试题
测绘工程个人的自我评价
2013/11/23 职场文书
医药个人求职信范文
2014/01/29 职场文书
医学类个人求职信范文
2014/02/05 职场文书
岗位说明书范文
2014/05/07 职场文书
干部选拔任用方案
2014/05/26 职场文书
2014党员学习《反腐倡廉警示教育读本》思想汇报
2014/09/13 职场文书
论文致谢词范文
2015/05/14 职场文书