新普金娱乐网址


杭城文艺范爆棚的茶舍们 | 清茶一杯,与谁人共同?

你打的《王者荣耀》有毒啊!

地理故宫养鹿变身皇家动物园?原来玄机都藏在这部中国老动画被!

  • 九月 09, 2018
  • 地理
  • 没有评论

今日博客开始连续创新,谢谢大家对自己之体贴以及支持。这几上一直是以形容一个ip代理池的开源项目。通过前几首的博客,我们得了解及突破反爬虫机制的一个要举动就是是代理ip。拥有粗大稳定的ip代理,在爬虫工作中以起及重点的图,但是自从财力的角度来说,一般稳定的ip池都好昂贵,因此自者开源项目的意义就诞生了,爬取一些摄网站提供的免费ip(虽然70%且是不好使的,但是扛不停歇量非常,网站多),检测中后存储到数据库中,同时搭建一个http服务器,提供一个api接口,供大家的爬虫程序调用。(自家的新书《Python爬虫开发与品类实战》公布了,大家在这边可以看到样章

前方数天,北京故宫出了一个“大新闻”:9只梅花鹿惊现紫禁城。故宫这是一旦“变身”皇家动物园的板?其实是吧配合“天禄永昌——故宫博物院藏瑞鹿文物特展”,故宫专门起承德避暑山庄引进参展的。

吓了,废话不多说,咱们上今天的主题,讲解一下己勾勒的斯开源项目IPProxys

中华文明中生久远的瑞鹿文化,这起“呦呦鹿鸣、鹤鹿同春、骑鹿寿星、鹿角椅、百鹿尊”等众神话传说和学识、实物遗存中全发生体现。

下面是这路之工程结构:

故宫藏鹤鹿同春寿星水晶雕件

api包:主要是实现http服务器,提供api接口(通过get请求,返回json数据)

不等之时,瑞鹿文化都以不同的样式与章程载体开展着显示表达:于神州卡通片的金年代,同样为生了扳平管辖对中华悠久瑞鹿文化进行展示的影视作品——《九色鹿》

data文件夹:主要是数据库文件之存储位置以及qqwry.dat(可以查询ip的地理位置)

改编自敦煌壁画《鹿王本生》、豆瓣评分8.7、钱家骏导演、上美厂出品、1981年播出之《九色鹿》,曾获得1985年水墨动画片制作工艺国家文化科学技术一等奖,及1986年加拿大汉密尔顿国际动画电影节特别荣誉奖。

db包:主要是包装了片数据库的操作

以小学僧看来,《九色鹿》是千篇一律总统珍贵的拿凡间的美丑、佛教里之因果、传统中之神仙祥瑞,以及瑞鹿文化等来如此深入浅出表达的作品。

spider包:主要是爬虫的为主职能,爬取代理网站及之代办ip

色彩中的风土人情文化

自当空间及之山岭地理,时间达到之星球、春夏秋冬,再至人世间的交替、繁简、冷暖、美丑等等,被中国古人从视觉及的情调加以区别,并致了再度老的知识意义。

敦煌壁画《鹿王本生》

设若仔细看罢《九色鹿》,能够察觉九色鹿并无是指“九种颜色的鹿”,九,为无限,是丰富多样。改编自敦煌壁画中舍己救人的九色鹿,与俗文化里“九色云中紫凤车”,所见来之光明祥瑞是平的。九色,美好都长。

色彩,同样是本着空中被的向地理在视觉和文化及的发表。《九色鹿》片中的商旅驼队穿过沙漠,远方的背景是五色山川。中国传统文化里含世界万物的金木水火土五行学说,对许向上之东边、西、南、北、中,延伸至色彩及虽然是黑、红、黄、白、黑五色。五色,为世界。

对于人世间美丑的发表,是色彩的别样一样十分效果。美之色,体白如雪的九色神鹿,自然大美的红花绿草,还有粉蝶穿梭其中。

品质的丑,包裹在华贵门面和皮囊下,王妃想以九色鹿皮为身穿之丑陋内心;恩将仇报、背弃誓言,遭受人身溃烂赤黑,臭的招苍蝇,红眼长舌,被打入拔舌地狱的捕蛇人。

test包:测试一些用例,不介入所有项目之运作

九色鹿·神兽·众生

于影视《九色鹿》里,对于外来佛教文化、中原知识和多文明交流而起的仙与动物瑞兽形象,除九色鹿外还有许多。

身姿曼妙、手舞琵琶、裸露上身、脖饰项链、腰系长裙、肩披彩带,带有浓厚中原文化之飞天。

印度高僧,用白马驮经至洛阳,将佛教传入汉地。

洛阳白马寺

下手加身,踏云追月,“如同牛王,无能胜故”的飞牛。

摩耶家梦白象入体内,生释迦摩尼。白象有四象牙、六牙的分:盖陀罗骑四象牙白象(影片中起的吧是四象牙白象),普贤仙的坐骑是六牙白象。

季象牙白象

季牙象石雕

发生龟蛇之体的玄武,与青龙、白虎、朱雀,共同构成中国神话中之四方的神。

玄武的前沿是一闪而过的朱雀

每个神与兽都起自己的任务,九色鹿,以鹿之如行佛之普度众生:为吃累死大漠的商旅指明前路,救困于水中枝杈上的蝼蚁和淹没的捕蛇人。

动物中生好也发出厌恶,《九色鹿》中的捕蛇人,可怜、可恶、可恨、可悲,把人性中贪瘘、背信、恶毒等“恶”的另一方面呈现得酣畅淋漓。

叫人奋勇争先去金钱,落入水中溺水,可怜;为了钱揭榜出卖九色鹿,可恶;自己作落水,引九色鹿进入包围,可恨;最终红眼长舌,坠入拔舌地狱,可悲。

值得嘉许的凡,为了见《九色鹿》捕蛇人作恶时之动作和心理活动,制作人员为夫形象进行了类似今天“表情包”式的著述:墙上阴影、胆小害怕、呆若木鸡、六神无主、汗如雨下、贪得无厌、阴险狡诈……

骑在尥蹶子黑驴、好像“皇协军带鬼子进村”一样的捕蛇人,溺水还非忘却拿那张满铜臭破纸……真是善恶到头终有回报。

util包:提供有工具类。IPAddress.py查询ip的地理位置

器以载道、大美本

否拿敦煌壁画及的《鹿王本生》故事,原汁原味地改编成为影视作品。《九色鹿》创作人员以敦煌底洞里待了23天,临摹出五那个本壁画素材。为24分钟之影片,创作了200不必要幅场景。

除此之外这些,小学僧还留意到不行年代的老动画人,对于风俗习惯器物与自风光之历史渊源,及其背后所承载的“器以载道、大美自然”有着极为深刻的回味

《九色鹿》导演钱家骏

录像开篇,那个照射出光芒的中原古要文化遗存——长信宫灯,这是小学僧看过之上美厂影片开篇处出现中国古重中之重文物的有数部有(另一样管是《镜花缘》出现的海兽纹葡萄镜)。以史为镜,观照古今,联通过去、现在同前景,当时或许是创作者选择铜镜和宫灯,作为一如既往总理历史故事题材动画片开篇之器的重中之重原由。

华先物质文化遗存何止千万,从中挑选多进入进艺术创作中,或会反映时代背景,或因器载道。在《九色鹿》的宫殿场景里,出现有一样起“马踏飞燕”,这宗发生土自甘肃武威的汉代文物,凡神州古丝绸之路文化要之文化缩影。而此部作品背景的敦煌知识,正是丝路文化之要部分。

能够像马踏飞燕之于丝路文化呈现要产生之文化交融,还有电影里皇帝为在的那张箱型壸门床。这种箱形家具,常见于佛教壁画中,其中敦煌壁画里也时有发生比多次之起。这种为宗教文化交流而来之箱型家具,对于中国唐宋以后家电的相来大死影响

华猿人在雅早以前就是打自受到营大美,并被本承载思想人文世界里之开门红与道法。这就是像鹿在中原所表示的福禄、吉祥、美好,甚至权。

电影里之自,有松鼠、小鸡、兔子围在九色鹿身旁,多子多福,是炎黄口传统的家中观。蝴蝶在消费草间穿梭,这是本之美好,也是华夏人于耄耋长寿之追求。黄莺以树上歌唱,中华士大夫精神世界里的本来,有“黄莺啼破纱窗晓”之美。

validator包:用来测试ip地址是否可用

倘呦呦鹿鸣,更如抗争群雄

任凭故宫里之梅花鹿,还是影片里的九色鹿,亦或者其他的瑞兽、吉祥、器物等等,都是中华文明为后人留下的珍贵且美好的财。

倘若中华传统文化的美,在于他的千家万户以及包容性:就算像故宫展览中那么张霸气十足、彰显游牧民族彪悍气息的鹿角椅,《九色鹿》中会师世间美好祥瑞于寥寥、扶危济困、惩恶扬善的九色鹿

故宫藏清代鹿角椅

当同样叫做中国总人口,我们必定要是打听自己文化基因里这种“当然人文和雄健豪迈”、相辅相成的抖和能力之达:比方呦呦鹿鸣,更如角逐群雄

config.py:主要是配置信息(包括布置ip地址之辨析方法和数据库的布置)

连着下谈一下重点代码:

先是说一下apiServer.py:

#coding:utf-8

'''

定义几个关键字,count types,protocol,country,area,

'''

import urllib

from config import API_PORT

from db.SQLiteHelper import SqliteHelper



__author__ = 'Xaxdus'



import BaseHTTPServer

import json

import urlparse



# keylist=['count', 'types','protocol','country','area']

class WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):



    def do_GET(self):

        """

        """

        dict={}



        parsed_path = urlparse.urlparse(self.path)

        try:

            query = urllib.unquote(parsed_path.query)

            print query

            if query.find('&')!=-1:

                params = query.split('&')

                for param in params:

                    dict[param.split('=')[0]]=param.split('=')[1]

            else:

                    dict[query.split('=')[0]]=query.split('=')[1]

            str_count=''

            conditions=[]

            for key in dict:

                if key =='count':

                    str_count = 'lIMIT 0,%s'% dict[key]

                if key =='country' or key =='area':

                    conditions .append(key+" LIKE '"+dict[key]+"%'")

                elif key =='types' or key =='protocol' or key =='country' or key =='area':

                    conditions .append(key+"="+dict[key])

            if len(conditions)>1:

                conditions = ' AND '.join(conditions)

            else:

                conditions =conditions[0]

            sqlHelper = SqliteHelper()

            result = sqlHelper.select(sqlHelper.tableName,conditions,str_count)

            # print type(result)

            # for r in  result:

            #     print r

            print result

            data = json.dumps(result)

            self.send_response(200)

            self.end_headers()

            self.wfile.write(data)

        except Exception,e:

            print e

            self.send_response(404)



if __name__=='__main__':

    server = BaseHTTPServer.HTTPServer(('0.0.0.0',API_PORT), WebRequestHandler)

    server.serve_forever()

自代码中好见见是针对性参数的辨析,参数包括count(数量),
types(模式),protocol(协议),country(国家),area(地区)
,(

types类型(0高匿名,1透明),protocol(0 http,1 https http),country(国家),area(省市))例如访问http://127.0.0.1:8000/?count=8&types=0.返回json数据。如下图所示:

紧接着说一下SQLiteHelper.py(主要是指向sqlite的操作):

#coding:utf-8

from config import DB_CONFIG

from db.SqlHelper import SqlHelper



__author__ = 'Xaxdus'

import sqlite3

class SqliteHelper(SqlHelper):



    tableName='proxys'

    def __init__(self):

        '''

        建立数据库的链接

        :return:

        '''

        self.database = sqlite3.connect(DB_CONFIG['dbPath'],check_same_thread=False)

        self.cursor = self.database.cursor()

        #创建表结构

        self.createTable()





    def createTable(self):

        self.cursor.execute("create TABLE IF NOT EXISTS %s (id INTEGER PRIMARY KEY ,ip VARCHAR(16) NOT NULL,"

               "port INTEGER NOT NULL ,types INTEGER NOT NULL ,protocol INTEGER NOT NULL DEFAULT 0,"

               "country VARCHAR (20) NOT NULL,area VARCHAR (20) NOT NULL,updatetime TimeStamp NOT NULL DEFAULT (datetime('now','localtime')) ,speed DECIMAL(3,2) NOT NULL DEFAULT 100)"% self.tableName)



        self.database.commit()



    def select(self,tableName,condition,count):

        '''



        :param tableName: 表名

        :param condition: 条件包含占位符

        :param value:  占位符所对应的值(主要是为了防注入)

        :return:

        '''

        command = 'SELECT DISTINCT ip,port FROM %s WHERE %s ORDER BY speed ASC %s '%(tableName,condition,count)



        self.cursor.execute(command)

        result = self.cursor.fetchall()

        return result



    def selectAll(self):

        self.cursor.execute('SELECT DISTINCT ip,port FROM %s ORDER BY speed ASC '%self.tableName)

        result = self.cursor.fetchall()

        return result



    def selectCount(self):

        self.cursor.execute('SELECT COUNT( DISTINCT ip) FROM %s'%self.tableName)

        count = self.cursor.fetchone()

        return count



    def selectOne(self,tableName,condition,value):

        '''



        :param tableName: 表名

        :param condition: 条件包含占位符

        :param value:  占位符所对应的值(主要是为了防注入)

        :return:

        '''

        self.cursor.execute('SELECT DISTINCT ip,port FROM %s WHERE %s ORDER BY speed ASC'%(tableName,condition),value)

        result = self.cursor.fetchone()

        return result



    def update(self,tableName,condition,value):

        self.cursor.execute('UPDATE %s %s'%(tableName,condition),value)

        self.database.commit()



    def delete(self,tableName,condition):

        '''



        :param tableName: 表名

        :param condition: 条件

        :return:

        '''

        deleCommand = 'DELETE FROM %s WHERE %s'%(tableName,condition)

        # print deleCommand

        self.cursor.execute(deleCommand)

        self.commit()



    def commit(self):

        self.database.commit()





    def insert(self,tableName,value):



        proxy = [value['ip'],value['port'],value['type'],value['protocol'],value['country'],value['area'],value['speed']]

        # print proxy

        self.cursor.execute("INSERT INTO %s (ip,port,types,protocol,country,area,speed)VALUES (?,?,?,?,?,?,?)"% tableName

                            ,proxy)





    def batch_insert(self,tableName,values):



        for value in values:

            if value!=None:

                self.insert(self.tableName,value)

        self.database.commit()





    def close(self):

        self.cursor.close()

        self.database.close()







if __name__=="__main__":

    s = SqliteHelper()

    print s.selectCount()[0]

    # print s.selectAll()

HtmlPraser.py(主要是对准html进行剖析):

使用lxml的xpath进展解析

#coding:utf-8

import datetime

from config import QQWRY_PATH, CHINA_AREA



from util.IPAddress import IPAddresss

from util.logger import logger



__author__ = 'Xaxdus'

from lxml import etree

class Html_Parser(object):



    def __init__(self):

        self.ips = IPAddresss(QQWRY_PATH)

    def parse(self,response,parser):

        '''



        :param response: 响应

        :param type: 解析方式

        :return:

        '''

        if parser['type']=='xpath':

            proxylist=[]

            root = etree.HTML(response)

            proxys = root.xpath(parser['pattern'])

            for proxy in proxys:

                # print parser['postion']['ip']

                ip = proxy.xpath(parser['postion']['ip'])[0].text

                port = proxy.xpath(parser['postion']['port'])[0].text

                type = proxy.xpath(parser['postion']['type'])[0].text

                if type.find(u'高匿')!=-1:

                    type = 0

                else:

                    type = 1

                protocol=''

                if len(parser['postion']['protocol']) > 0:

                    protocol = proxy.xpath(parser['postion']['protocol'])[0].text

                    if protocol.lower().find('https')!=-1:

                        protocol = 1

                    else:

                        protocol = 0

                else:

                    protocol = 0

                addr = self.ips.getIpAddr(self.ips.str2ip(ip))

                country = ''

                area = ''

                if addr.find(u'省')!=-1 or self.AuthCountry(addr):

                    country = u'中国'

                    area = addr

                else:

                    country = addr

                    area = ''

                # updatetime = datetime.datetime.now()

                # ip,端口,类型(0高匿名,1透明),protocol(0 http,1 https http),country(国家),area(省市),updatetime(更新时间)



                # proxy ={'ip':ip,'port':int(port),'type':int(type),'protocol':int(protocol),'country':country,'area':area,'updatetime':updatetime,'speed':100}

                proxy ={'ip':ip,'port':int(port),'type':int(type),'protocol':int(protocol),'country':country,'area':area,'speed':100}

                print proxy

                proxylist.append(proxy)



            return proxylist



    def AuthCountry(self,addr):

        '''

        用来判断地址是哪个国家的

        :param addr:

        :return:

        '''

        for area in CHINA_AREA:

            if addr.find(area)!=-1:

                return True

        return False

IPAddresss.py(通过读取纯真qqwry.dat,对ip地址进行定位),读取的方式可以参考:http://ju.outofmemory.cn/entry/85998;https://linuxtoy.org/archives/python-ip.html

#! /usr/bin/env python

# -*- coding: utf-8 -*-







import socket

import struct





class IPAddresss:

    def __init__(self, ipdbFile):

        self.ipdb = open(ipdbFile, "rb")

        str = self.ipdb.read(8)

        (self.firstIndex, self.lastIndex) = struct.unpack('II', str)

        self.indexCount = (self.lastIndex - self.firstIndex)/7+1

        # print self.getVersion(), u" 纪录总数: %d 条 "%(self.indexCount)



    def getVersion(self):

        s = self.getIpAddr(0xffffff00L)

        return s



    def getAreaAddr(self, offset=0):

        if offset:

            self.ipdb.seek(offset)

        str = self.ipdb.read(1)

        (byte,) = struct.unpack('B', str)

        if byte == 0x01 or byte == 0x02:

            p = self.getLong3()

            if p:

                return self.getString(p)

            else:

                return ""

        else:

            self.ipdb.seek(-1, 1)

            return self.getString(offset)



    def getAddr(self, offset, ip=0):

        self.ipdb.seek(offset + 4)

        countryAddr = ""

        areaAddr = ""

        str = self.ipdb.read(1)

        (byte,) = struct.unpack('B', str)

        if byte == 0x01:

            countryOffset = self.getLong3()

            self.ipdb.seek(countryOffset)

            str = self.ipdb.read(1)

            (b,) = struct.unpack('B', str)

            if b == 0x02:

                countryAddr = self.getString(self.getLong3())

                self.ipdb.seek(countryOffset + 4)

            else:

                countryAddr = self.getString(countryOffset)

            areaAddr = self.getAreaAddr()

        elif byte == 0x02:

            countryAddr = self.getString(self.getLong3())

            areaAddr = self.getAreaAddr(offset + 8)

        else:

            countryAddr = self.getString(offset + 4)

            areaAddr = self.getAreaAddr()

        return countryAddr + " " + areaAddr



    def dump(self, first , last):

        if last > self.indexCount :

            last = self.indexCount

        for index in range(first, last):

            offset = self.firstIndex + index * 7

            self.ipdb.seek(offset)

            buf = self.ipdb.read(7)

            (ip, of1, of2) = struct.unpack("IHB", buf)

            address = self.getAddr(of1 + (of2 << 16))

            # 把GBK转为utf-8

            address = unicode(address, 'gbk').encode("utf-8")

            print "%d\t%s\t%s" % (index, self.ip2str(ip), address)



    def setIpRange(self, index):

        offset = self.firstIndex + index * 7

        self.ipdb.seek(offset)

        buf = self.ipdb.read(7)

        (self.curStartIp, of1, of2) = struct.unpack("IHB", buf)

        self.curEndIpOffset = of1 + (of2 << 16)

        self.ipdb.seek(self.curEndIpOffset)

        buf = self.ipdb.read(4)

        (self.curEndIp,) = struct.unpack("I", buf)



    def getIpAddr(self, ip):

        L = 0

        R = self.indexCount - 1

        while L < R-1:

            M = (L + R) / 2

            self.setIpRange(M)

            if ip == self.curStartIp:

                L = M

                break

            if ip > self.curStartIp:

                L = M

            else:

                R = M

        self.setIpRange(L)

        # version information, 255.255.255.X, urgy but useful

        if ip & 0xffffff00L == 0xffffff00L:

            self.setIpRange(R)

        if self.curStartIp <= ip <= self.curEndIp:

            address = self.getAddr(self.curEndIpOffset)

            # 把GBK转为utf-8

            address = unicode(address, 'gbk')

        else:

            address = u"未找到该IP的地址"

        return address



    def getIpRange(self, ip):

        self.getIpAddr(ip)

        range = self.ip2str(self.curStartIp) + ' - ' \

            + self.ip2str(self.curEndIp)

        return range



    def getString(self, offset = 0):

        if offset :

            self.ipdb.seek(offset)

        str = ""

        ch = self.ipdb.read(1)

        (byte,) = struct.unpack('B', ch)

        while byte != 0:

            str += ch

            ch = self.ipdb.read(1)

            (byte,) = struct.unpack('B', ch)

        return str



    def ip2str(self, ip):

        return str(ip >> 24)+'.'+str((ip >> 16) & 0xffL)+'.'+str((ip >> 8) & 0xffL)+'.'+str(ip & 0xffL)



    def str2ip(self, s):

        (ip,) = struct.unpack('I', socket.inet_aton(s))

        return ((ip >> 24) & 0xffL) | ((ip & 0xffL) << 24) | ((ip >> 8) & 0xff00L) | ((ip & 0xff00L) << 8)



    def getLong3(self, offset=0):

        if offset:

            self.ipdb.seek(offset)

        str = self.ipdb.read(3)

        (a, b) = struct.unpack('HB', str)

        return (b << 16) + a

末尾看一下validator.py,由于应用的凡python2.7,所以一旦下协程采用了gevent:

#coding:utf-8

import datetime

from gevent.pool import Pool

import requests

import time

from config import TEST_URL

import config

from db.SQLiteHelper import SqliteHelper

from gevent import monkey

monkey.patch_all()

__author__ = 'Xaxdus'



class Validator(object):



    def __init__(self):

        self.detect_pool = Pool(config.THREADNUM)





    def __init__(self,sqlHelper):

        self.detect_pool = Pool(config.THREADNUM)

        self.sqlHelper =sqlHelper





    def run_db(self):

        '''

        从数据库中检测

        :return:

        '''

        try:

            #首先将超时的全部删除

            self.deleteOld()

            #接着将重复的删除掉



            #接着检测剩余的ip,是否可用

            results = self.sqlHelper.selectAll()

            self.detect_pool.map(self.detect_db,results)

            return self.sqlHelper.selectCount()#返回最终的数量

        except Exception,e:

            print e

            return 0







    def run_list(self,results):

        '''

        这个是先不进入数据库,直接从集合中删除

        :param results:

        :return:

        '''

        # proxys=[]

        # for result in results:

        proxys = self.detect_pool.map(self.detect_list,results)

        #这个时候proxys的格式是[{},{},{},{},{}]

        return proxys













    def deleteOld(self):

        '''

        删除旧的数据

        :return:

        '''

        condition = "updatetime<'%s'"%((datetime.datetime.now() - datetime.timedelta(minutes=config.MAXTIME)).strftime('%Y-%m-%d %H:%M:%S'))

        self.sqlHelper.delete(SqliteHelper.tableName,condition)











    def detect_db(self,result):

        '''



        :param result: 从数据库中检测

        :return:

        '''

        ip = result[0]

        port = str(result[1])

        proxies={"http": "http://%s:%s"%(ip,port)}

        start = time.time()

        try:

            r = requests.get(url=TEST_URL,headers=config.HEADER,timeout=config.TIMEOUT,proxies=proxies)



            if not r.ok:

                condition = "ip='"+ip+"' AND "+'port='+port

                print 'fail ip =%s'%ip

                self.sqlHelper.delete(SqliteHelper.tableName,condition)

            else:

                speed = round(time.time()-start, 2)

                self.sqlHelper.update(SqliteHelper.tableName,'SET speed=? WHERE ip=? AND port=?',(speed,ip,port))

                print 'success ip =%s,speed=%s'%(ip,speed)

        except Exception,e:

                condition = "ip='"+ip+"' AND "+'port='+port

                print 'fail ip =%s'%ip

                self.sqlHelper.delete(SqliteHelper.tableName,condition)







    def detect_list(self,proxy):

        '''

        :param proxy: ip字典

        :return:

        '''

        # for proxy in proxys:



        ip = proxy['ip']

        port = proxy['port']

        proxies={"http": "http://%s:%s"%(ip,port)}

        start = time.time()

        try:

            r = requests.get(url=TEST_URL,headers=config.HEADER,timeout=config.TIMEOUT,proxies=proxies)



            if not r.ok:

                print 'fail ip =%s'%ip

                proxy = None



            else:

                speed = round(time.time()-start,2)

                print 'success ip =%s,speed=%s'%(ip,speed)

                proxy['speed']=speed

                # return proxy

        except Exception,e:

                print 'fail ip =%s'%ip

                proxy = None

        return proxy

        # return proxys





if __name__=='__main__':

    # v = Validator()

    # results=[{'ip':'192.168.1.1','port':80}]*10

    # results = v.run(results)

    # print results

    pass

最后咱们看一下运行效果: 切换到工程目录下,cmd中执行python IPProxys.py:

其一时候咱们在浏览器被输入请求,就会见回到响应的结果:

履流程是各国隔半钟头检测时而数据库被ip地址之中,抹无效的代办ip。如果ip地址数据少一个数值,爬虫将会见启动,进行新一轱辘的爬取。当然检测时间和数据量且得在config.py中安排。咱们看一下config.py的有些代码,大家就是明白了:

'''

数据库的配置

'''

DB_CONFIG={

    'dbType':'sqlite',#sqlite,mysql,mongodb

    'dbPath':'./data/proxy.db',#这个仅仅对sqlite有效

    'dbUser':'',#用户名

    'dbPass':'',#密码

    'dbName':''#数据库名称



}



CHINA_AREA=[u'河北',u'山东',u'辽宁',u'黑龙江',u'吉林'

    ,u'甘肃',u'青海',u'河南',u'江苏',u'湖北',u'湖南',

            u'江西',u'浙江',u'广东',u'云南',u'福建',

            u'台湾',u'海南',u'山西',u'四川',u'陕西',

            u'贵州',u'安徽',u'重庆',u'北京',u'上海',u'天津',u'广西',u'内蒙',u'西藏',u'新疆',u'宁夏',u'香港',u'澳门']

QQWRY_PATH="./data/qqwry.dat"



THREADNUM = 20

API_PORT=8000

'''

爬虫爬取和检测ip的设置条件

不需要检测ip是否已经存在,因为会定时清理

'''

UPDATE_TIME=30*60#每半个小时检测一次是否有代理ip失效

MINNUM = 500 #当有效的ip值小于一个时 需要启动爬虫进行爬取

MAXTIME = 24*60 #当爬取存储开始一直使用的最大时间,如果超过这个时间,都删除



TIMEOUT = 5#socket延时







'''

反爬虫的设置

'''

'''

重试次数

'''

RETRY_TIME=3





'''

USER_AGENTS 随机头信息

'''

USER_AGENTS = [

    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",

    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",

    "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",

    "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",

    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",

    "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",

    "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",

    "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",

    "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",

    "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",

    "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",

    "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",

    "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",

    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",

    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",

    "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",

    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11",

    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER",

    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; LBBROWSER)",

    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)",

    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 LBBROWSER",

    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)",

    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.0.3698.400)",

    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)",

    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; 360SE)",

    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)",

    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)",

    "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1",

    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1",

    "Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5",

    "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b13pre) Gecko/20110307 Firefox/4.0b13pre",

    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:16.0) Gecko/20100101 Firefox/16.0",

    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11",

    "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10"

]



HEADER = {

    'User-Agent': random.choice(USER_AGENTS),

    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',

    'Accept-Language': 'en-US,en;q=0.5',

    'Connection': 'keep-alive',

    'Accept-Encoding': 'gzip, deflate',

}



TEST_URL='http://www.ip138.com/'

所有项目的代码很简短,大家要想深入摸底的话,就详细的圈一下自的之初步源项目IPProxys代码,代码写的有些粗糙,日后重累优化。

完整的代码我已经上传到github上:https://github.com/qiyeboy/IPProxys
qqwry.dat下载链接:http://pan.baidu.com/s/1o7A6n8m 密码:wcvs。

今天的分享就到这里,如果大家觉得还可以呀,记得赞赏呦。

相关文章

No Comments, Be The First!
近期评论
    分类目录
    功能
    网站地图xml地图