├── pylinktester ├── readme.md ├── core │ ├── __init__.py │ ├── bfs.pyc │ ├── test.pyc │ ├── __init__.pyc │ ├── bfs.py │ └── test.py ├── model │ ├── __init__.py │ ├── urlSync.pyc │ ├── __init__.pyc │ ├── urlQuence.pyc │ ├── urlSync.py │ └── urlQuence.py ├── threads │ ├── __init__.py │ ├── __init__.pyc │ ├── testThread.pyc │ ├── spliderThread.pyc │ ├── threadController.pyc │ ├── testThread.py │ ├── spliderThread.py │ └── threadController.py ├── utils │ ├── __init__.py │ ├── getUrls.pyc │ ├── __init__.pyc │ ├── testUrls.pyc │ ├── getRequest.pyc │ ├── getUrls.py │ ├── testUrls.py │ └── getRequest.py ├── .gitignore ├── main.py └── logs │ └── 2014-02-08.txt ├── sphinx ├── _build │ ├── html │ │ ├── objects.inv │ │ ├── _static │ │ │ ├── down.png │ │ │ ├── file.png │ │ │ ├── plus.png │ │ │ ├── up.png │ │ │ ├── minus.png │ │ │ ├── comment.png │ │ │ ├── ajax-loader.gif │ │ │ ├── up-pressed.png │ │ │ ├── comment-bright.png │ │ │ ├── comment-close.png │ │ │ ├── down-pressed.png │ │ │ ├── pygments.css │ │ │ ├── default.css │ │ │ ├── sidebar.js │ │ │ ├── doctools.js │ │ │ ├── underscore.js │ │ │ ├── basic.css │ │ │ ├── searchtools.js │ │ │ ├── websupport.js │ │ │ └── jquery.js │ │ ├── searchindex.js │ │ ├── .buildinfo │ │ ├── _sources │ │ │ └── index.txt │ │ ├── genindex.html │ │ ├── search.html │ │ └── index.html │ └── doctrees │ │ ├── index.doctree │ │ └── environment.pickle ├── index.rst ├── make.bat ├── Makefile └── conf.py ├── .gitignore └── README.md /pylinktester/readme.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pylinktester/core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pylinktester/model/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pylinktester/threads/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pylinktester/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pylinktester/core/bfs.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/core/bfs.pyc -------------------------------------------------------------------------------- /pylinktester/core/test.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/core/test.pyc -------------------------------------------------------------------------------- /pylinktester/core/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/core/__init__.pyc -------------------------------------------------------------------------------- /pylinktester/model/urlSync.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/model/urlSync.pyc -------------------------------------------------------------------------------- /pylinktester/utils/getUrls.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/utils/getUrls.pyc -------------------------------------------------------------------------------- /sphinx/_build/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/objects.inv -------------------------------------------------------------------------------- /pylinktester/model/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/model/__init__.pyc -------------------------------------------------------------------------------- /pylinktester/model/urlQuence.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/model/urlQuence.pyc -------------------------------------------------------------------------------- /pylinktester/utils/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/utils/__init__.pyc -------------------------------------------------------------------------------- /pylinktester/utils/testUrls.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/utils/testUrls.pyc -------------------------------------------------------------------------------- /pylinktester/threads/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/threads/__init__.pyc -------------------------------------------------------------------------------- /pylinktester/threads/testThread.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/threads/testThread.pyc -------------------------------------------------------------------------------- /pylinktester/utils/getRequest.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/utils/getRequest.pyc -------------------------------------------------------------------------------- /sphinx/_build/html/_static/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/_static/down.png -------------------------------------------------------------------------------- /sphinx/_build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/_static/file.png -------------------------------------------------------------------------------- /sphinx/_build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/_static/plus.png -------------------------------------------------------------------------------- /sphinx/_build/html/_static/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/_static/up.png -------------------------------------------------------------------------------- /sphinx/_build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/doctrees/index.doctree -------------------------------------------------------------------------------- /sphinx/_build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/_static/minus.png -------------------------------------------------------------------------------- /pylinktester/threads/spliderThread.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/threads/spliderThread.pyc -------------------------------------------------------------------------------- /sphinx/_build/html/_static/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/_static/comment.png -------------------------------------------------------------------------------- /pylinktester/threads/threadController.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/pylinktester/threads/threadController.pyc -------------------------------------------------------------------------------- /sphinx/_build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/doctrees/environment.pickle -------------------------------------------------------------------------------- /sphinx/_build/html/_static/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/_static/ajax-loader.gif -------------------------------------------------------------------------------- /sphinx/_build/html/_static/up-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/_static/up-pressed.png -------------------------------------------------------------------------------- /sphinx/_build/html/_static/comment-bright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/_static/comment-bright.png -------------------------------------------------------------------------------- /sphinx/_build/html/_static/comment-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/_static/comment-close.png -------------------------------------------------------------------------------- /sphinx/_build/html/_static/down-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flowerowl/pylinktester/HEAD/sphinx/_build/html/_static/down-pressed.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.log 3 | *.pyc 4 | .idea 5 | run 6 | build 7 | dist 8 | .project 9 | .pydevproject 10 | atlassian-ide-plugin.xml 11 | build 12 | dist 13 | *.egg-info 14 | logs 15 | .noseids 16 | .coverage 17 | cover 18 | install 19 | .env 20 | -------------------------------------------------------------------------------- /sphinx/_build/html/searchindex.js: -------------------------------------------------------------------------------- 1 | Search.setIndex({objects:{},terms:{index:0,search:0,pylinktest:0,welcom:0,modul:0,indic:0,content:0,tabl:0,document:0,page:0},objtypes:{},titles:["Welcome to pylinktester’s documentation!"],objnames:{},filenames:["index"]}) -------------------------------------------------------------------------------- /sphinx/_build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 6175db360de31d3f40617f547ccd3764 4 | tags: fbb0d17656682115ca4d033fb2f83ba1 5 | -------------------------------------------------------------------------------- /sphinx/index.rst: -------------------------------------------------------------------------------- 1 | .. pylinktester documentation master file, created by 2 | sphinx-quickstart on Tue Nov 19 16:56:57 2013. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to pylinktester's documentation! 7 | ======================================== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | 15 | 16 | Indices and tables 17 | ================== 18 | 19 | * :ref:`genindex` 20 | * :ref:`modindex` 21 | * :ref:`search` 22 | 23 | -------------------------------------------------------------------------------- /sphinx/_build/html/_sources/index.txt: -------------------------------------------------------------------------------- 1 | .. pylinktester documentation master file, created by 2 | sphinx-quickstart on Tue Nov 19 16:56:57 2013. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to pylinktester's documentation! 7 | ======================================== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | 15 | 16 | Indices and tables 17 | ================== 18 | 19 | * :ref:`genindex` 20 | * :ref:`modindex` 21 | * :ref:`search` 22 | 23 | -------------------------------------------------------------------------------- /pylinktester/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | 3 | # https://github.com/github/gitignore/blob/master/Python.gitignore 4 | *.py[cod] 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Packages 10 | *.egg 11 | *.egg-info 12 | dist 13 | build 14 | eggs 15 | parts 16 | bin 17 | var 18 | sdist 19 | develop-eggs 20 | .installed.cfg 21 | lib 22 | lib64 23 | __pycache__ 24 | 25 | # Installer logs 26 | pip-log.txt 27 | 28 | # Unit test / coverage reports 29 | .coverage 30 | .tox 31 | nosetests.xml 32 | 33 | # Translations 34 | *.mo 35 | 36 | # Mr Developer 37 | .mr.developer.cfg 38 | .project 39 | .pydevproject 40 | 41 | mcms/db.sqlite3 42 | -------------------------------------------------------------------------------- /pylinktester/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import model.urlQuence as urlQuence 4 | import threads.threadController as tc 5 | import model.urlSync as urlSync 6 | 7 | 8 | if __name__=="__main__": 9 | seed = set(["http://m.sohu.com"]) #初始url,算作第一层链接 10 | threadNumber = 10 #线程数 11 | deepth = 5 #设置爬取深度 12 | urlQuence = urlQuence.urlQuence(deepth+1) #初始化deepth个set,存放相应层数未访问链接 13 | urlQuence.addUnvisitedUrl(seed, 1) #seed链接算作第一层 14 | urlSync = urlSync.urlSync() #为testThread同步未访问的url集合 15 | tc = tc.threadController(threadNumber, urlQuence, urlSync, deepth) #初始化线程管理器 16 | tc.start() 17 | -------------------------------------------------------------------------------- /pylinktester/threads/testThread.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import threading 4 | import sys 5 | sys.path.insert(0, r'..') 6 | 7 | import core.test as core 8 | 9 | class testThread(threading.Thread): 10 | ''' 11 | 检测线程 12 | ''' 13 | 14 | def __init__(self, urlSync, spliderThreadPool, mutex): 15 | threading.Thread.__init__(self) 16 | self.setDaemon(True) 17 | #链接队列 18 | self.urlSync = urlSync 19 | #爬虫线程池,用来检测爬虫是否已死 20 | self.spliderThreadPool = spliderThreadPool 21 | self.mutex = mutex 22 | 23 | def run(self): 24 | core.test(self.urlSync, self.spliderThreadPool, self.mutex) 25 | -------------------------------------------------------------------------------- /pylinktester/threads/spliderThread.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import threading 4 | import sys 5 | sys.path.insert(0, r'..') 6 | 7 | import core.bfs as core 8 | 9 | class spliderThread(threading.Thread): 10 | ''' 11 | 爬虫线程 12 | 采用广度优先算法 13 | ''' 14 | 15 | def __init__(self, urlQuence, urlSync, deepth, mutex): 16 | threading.Thread.__init__(self) 17 | self.setDaemon(True) 18 | #保存爬取链接的集合 19 | self.urlQuence = urlQuence 20 | #同时需要更新的供检测线程使用的队列 21 | self.urlSync = urlSync 22 | #爬取深度 23 | self.deepth = deepth 24 | self.mutex = mutex 25 | 26 | def run(self): 27 | core.bfs(self.urlQuence, self.urlSync, self.deepth, self.mutex) 28 | -------------------------------------------------------------------------------- /pylinktester/utils/getUrls.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import urllib2 4 | import sys 5 | 6 | from bs4 import BeautifulSoup 7 | 8 | import testUrls 9 | import getRequest 10 | 11 | reload(sys) 12 | sys.setdefaultencoding("utf-8") 13 | 14 | def geturls(url): 15 | ''' 16 | 获取当前页所有链接 17 | ''' 18 | source = getsource(url) 19 | urlset = set() 20 | try: 21 | soup = BeautifulSoup(source) 22 | except: 23 | return urlset 24 | for link in soup.find_all('a'): 25 | if link.get('href') is not None and (link.get('href')[:4] \ 26 | == 'http' or link.get('href')[:1] == '/'): 27 | if link.get('href')[:4] == 'http': 28 | urlset.add(link.get('href')) 29 | if link.get('href')[:1] == '/': 30 | urlset.add('http://m.sohu.com'+link.get('href')) 31 | return urlset 32 | 33 | 34 | def getsource(url): 35 | ''' 36 | 获取当前网页源码 37 | ''' 38 | req, opener = getRequest.getRequest(url) 39 | try: 40 | urlopen = opener.open(req, timeout = 10) 41 | source = urlopen.read() 42 | return source 43 | except Exception: 44 | testUrls.testUrls(url) 45 | -------------------------------------------------------------------------------- /pylinktester/model/urlSync.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import Queue 5 | 6 | class urlSync(): 7 | ''' 8 | 为检测线程创建一个队列,同时爬虫线程向此队列添加 9 | ''' 10 | 11 | def __init__(self): 12 | #链接队列 13 | self.urlQue = Queue.Queue() 14 | #已检测过的链接 15 | self.visited = set() 16 | #临时集合,用来去重 17 | self.tempSet = set() 18 | #获取未访问的链接 19 | def getUnvisitedUrl(self): 20 | try: 21 | return self.urlQue.get(block=True, timeout=2.0) 22 | except Exception, e: 23 | print "[EXCEPTION] getUnvisitedUrl() - EMPTY" 24 | return None 25 | #添加未访问的链接 26 | def addUnvisitedUrl(self, urls): 27 | self.tempSet.update(urls) 28 | for url in (self.tempSet - (self.tempSet & self.visited)): 29 | self.urlQue.put(url) 30 | self.tempSet.clear() 31 | #获取未访问链接数目 32 | def getUnvistedUrlCount(self): 33 | return self.urlQue.qsize() 34 | #获取已访问链接 35 | def getVisitedUrl(self): 36 | return self.visited 37 | #获取访问过的链接数目 38 | def getVisitedUrlCount(self): 39 | return len(self.visited) 40 | #添加已访问过的链接 41 | def addVisistedUrl(self, url): 42 | self.visited.add(url) 43 | -------------------------------------------------------------------------------- /pylinktester/core/bfs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import sys 4 | import threading 5 | sys.path.insert(0, r'..') 6 | 7 | import utils.getUrls as utils 8 | 9 | 10 | def bfs(urlQuence, urlSync, deepth, mutex): 11 | ''' 12 | 广度优先算法,按层提取/存放链接 13 | ''' 14 | 15 | current = urlQuence.getLayerunVisited() #当前未访问的最小层数 16 | while current is not None and current < deepth+1 : 17 | #从当前层提取一个未访问链接 18 | #print "bfs-mutex.acquire()..." 19 | mutex.acquire() 20 | #print "bfs-mutex.acquire() OK" 21 | visitUrl = urlQuence.unVisitedUrlDeQuence(current) 22 | mutex.release() 23 | #print "bfs-mutex.release() OK" 24 | print "第%d层未访问链接出队 \"%s\" "%(current, visitUrl) 25 | if visitUrl is None or visitUrl=="": 26 | break 27 | #获取超链接,set() 28 | links = utils.geturls(visitUrl) 29 | #将url放入已访问的url中 30 | urlQuence.addVisitedUrl(visitUrl) 31 | #未访问的url入列 32 | #print "bfs-2-mutex.acquire()..." 33 | mutex.acquire() 34 | #print "bfs-2-mutex.acquire() OK" 35 | urlQuence.addUnvisitedUrl(links, current+1) 36 | urlSync.addUnvisitedUrl(links) 37 | mutex.release() 38 | #print "bfs-2-mutex.release() OK" 39 | current = urlQuence.getLayerunVisited() 40 | -------------------------------------------------------------------------------- /pylinktester/core/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import sys 4 | sys.path.insert(0, r'..') 5 | import threading 6 | 7 | import utils.testUrls as utils 8 | 9 | def test(urlSync, spliderThreadPool, mutex): 10 | ''' 11 | 检测链接的调度器 12 | ''' 13 | 14 | while urlSync.getUnvistedUrlCount() != 0 or spliderIsAlive(spliderThreadPool): 15 | #print "test-mutex.acquire()..." 16 | mutex.acquire() 17 | #print "test-mutex.acquire() OK" 18 | url = urlSync.getUnvisitedUrl() 19 | mutex.release() 20 | #print "test-mutex.release() OK" 21 | if url in urlSync.visited: 22 | continue 23 | if url is None: 24 | print '剩余链接数量',urlSync.getUnvistedUrlCount() 25 | for st in spliderThreadPool: 26 | print st.getName(),st.isAlive() 27 | continue 28 | print threading.currentThread() 29 | #检测链接 30 | utils.testUrls(url) 31 | #print "test-2-mutex.acquire()..." 32 | mutex.acquire() 33 | #print "test-2-mutex.acquire()OK" 34 | urlSync.addVisistedUrl(url) 35 | mutex.release() 36 | #print "test-2-mutex.release()OK" 37 | print '剩余链接数量',urlSync.getUnvistedUrlCount() 38 | 39 | def spliderIsAlive(spliderThreadPool): 40 | ''' 41 | 判断爬虫是否已死 42 | ''' 43 | 44 | for st in spliderThreadPool: 45 | if st.isAlive(): 46 | return True 47 | return False 48 | -------------------------------------------------------------------------------- /pylinktester/threads/threadController.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import time 4 | import threading 5 | 6 | import spliderThread, testThread 7 | 8 | global g_mutex 9 | g_mutex = threading.Lock() 10 | 11 | class threadController: 12 | ''' 13 | 线程管理器,初始化爬虫/检测线程,运行完退出 14 | ''' 15 | 16 | def __init__(self, threadNumber, urlQuence, urlSync, deepth): 17 | self.threadNumber = threadNumber 18 | self.urlQuence = urlQuence 19 | self.urlSync = urlSync 20 | self.deepth = deepth 21 | self.spliderThreadPool = [] 22 | self.testThreadPool = [] 23 | self.mutex = g_mutex 24 | def start(self): 25 | for i in range(self.threadNumber): 26 | self.runSplider() 27 | if i == 0: #第一个爬虫需要爬一些预备链接供之后的爬虫使用 28 | time.sleep(10) 29 | #等待爬虫线程都开启之后再开启测试线程 30 | for i in range(self.threadNumber * 2): 31 | self.runTest() 32 | 33 | self.waitUntilEnd() 34 | 35 | def runSplider(self): 36 | st = spliderThread.spliderThread(self.urlQuence, self.urlSync, self.deepth, self.mutex) 37 | self.spliderThreadPool.append(st) 38 | st.start() 39 | 40 | def runTest(self): 41 | tt = testThread.testThread(self.urlSync, self.spliderThreadPool, self.mutex) 42 | self.testThreadPool.append(tt) 43 | tt.start() 44 | 45 | def waitUntilEnd(self): 46 | for st in self.spliderThreadPool: 47 | st.join() 48 | print "spliderThread[%s] 爬取完毕!" % st.getName() 49 | for tt in self.testThreadPool: 50 | tt.join() 51 | print "testThread[%s] 检测完毕!" % tt.getName() 52 | -------------------------------------------------------------------------------- /pylinktester/utils/testUrls.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import urllib2 5 | import threading 6 | import os.path 7 | import time 8 | import socket 9 | 10 | import getRequest 11 | 12 | global g_mutex 13 | g_mutex = threading.Lock() 14 | 15 | def testUrls(url, repeat = 3): 16 | ''' 17 | 真正干活的检测链接函数,设置超时访问次数为三次 18 | ''' 19 | 20 | ti = time.strftime('%Y-%m-%d %H:%M:%S ',time.localtime(time.time())) 21 | if url is not None: 22 | req, opener = getRequest.getRequest(url) 23 | try: 24 | urlopen = opener.open(req, timeout = 10) 25 | except urllib2.HTTPError, ex: 26 | if(repeat > 0): 27 | testUrls(url, repeat - 1) 28 | else: 29 | log(str(ex), ti, url) 30 | except urllib2.URLError, ex: 31 | if(repeat > 0): 32 | testUrls(url, repeat - 1) 33 | else: 34 | log(str(ex), ti, url) 35 | except socket.timeout as ex: 36 | if(repeat > 0): 37 | testUrls(url, repeat - 1) 38 | else: 39 | log(str(ex), ti, url) 40 | 41 | 42 | def log(error, ti, url): 43 | ''' 44 | 记录日志 45 | ''' 46 | path = getLogsPath() 47 | print "log-mutex.acquire()..." 48 | g_mutex.acquire() 49 | print "log-mutex.acquire() OK" 50 | fileHandle = open (path+str(time.strftime('%Y-%m-%d'))+'.txt', 'a') 51 | fileHandle.write(ti+error+url+'\r\n') 52 | fileHandle.close() 53 | g_mutex.release() 54 | print "log-mutex.release() OK" 55 | 56 | 57 | def getLogsPath(): 58 | ''' 59 | 获取日志路径,若没有则创建 60 | ''' 61 | path = os.path.dirname(__file__) 62 | newpath = '/'.join(path.split('/')[:-1])+'/logs/' 63 | if(not os.path.exists(newpath)): 64 | os.mkdir(newpath) 65 | return newpath 66 | -------------------------------------------------------------------------------- /pylinktester/model/urlQuence.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | global uv 5 | 6 | class urlQuence: 7 | ''' 8 | 爬虫线程的链接保存集合,按层分配,一层一个set() 9 | ''' 10 | 11 | def __init__(self, deepth): 12 | #已访问的url集合 13 | self.visited=set() 14 | #设定爬去深度 15 | self.deepth = deepth 16 | #未访问的url字典,按层数做key 17 | self.unVisited = {} 18 | 19 | for i in range(self.deepth): 20 | self.unVisited[i+1] = set() 21 | 22 | #获取访问过的url集合 23 | def getVisitedUrl(self): 24 | return self.visited 25 | #获取未访问的url集合 26 | def getUnvisitedUrl(self): 27 | uv = set() 28 | for i, s in self.unVisited.items(): 29 | uv |= s 30 | return uv 31 | #添加到访问过得url队列中 32 | def addVisitedUrl(self, url): 33 | self.visited.add(url) 34 | #移除访问过得url 35 | def removeVisitedUrl(self, url): 36 | self.visited.remove(url) 37 | #按层提取未访问过得url 38 | def unVisitedUrlDeQuence(self, deepth): 39 | try: 40 | return self.unVisited[deepth].pop() 41 | except: 42 | return None 43 | #按层插入未访问url 44 | def addUnvisitedUrl(self, url, deepth): 45 | self.unVisited[deepth].update(url) 46 | #获得已访问的url数目 47 | def getVisitedUrlCount(self): 48 | return len(self.visited) 49 | #获得未访问的url数目 50 | def getUnvistedUrlCount(self): 51 | count = 0 52 | for i in range(self.deepth): 53 | count += len(self.unVisited[i+1]) 54 | return count 55 | #获取指定层数未访问链接数目 56 | def getUnvisitedUrlCountByDeepth(self, deepth): 57 | return len(self.unVisited[deepth]) 58 | #判断未访问的url集合是否为空,返回最小非空层 59 | def getLayerunVisited(self): 60 | for i in range(self.deepth): 61 | if len(self.unVisited[i+1]) != 0: 62 | return i+1 63 | 64 | 65 | -------------------------------------------------------------------------------- /pylinktester/utils/getRequest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | from StringIO import StringIO 4 | import urllib2 5 | 6 | from gzip import GzipFile 7 | 8 | def getRequest(url): 9 | ''' 10 | 包装urllib2的请求 11 | ''' 12 | encoding_support = ContentEncodingProcessor 13 | opener = urllib2.build_opener(encoding_support, urllib2.HTTPHandler) 14 | req = urllib2.Request(url) 15 | req.add_header('User-Agent','Mozilla/5.0 (Windows;U;Windows NT 5.1;zh-CN;rv:1.9.2.9)Gecko/20100824Firefox/3.6.9') 16 | return req, opener 17 | 18 | 19 | class ContentEncodingProcessor(urllib2.BaseHandler): 20 | ''' 21 | 支持gzip,defalte,加快加载速度 22 | ref:http://www.pythonclub.org/python-network-application/observer-spider 23 | ''' 24 | 25 | """A handler to add gzip capabilities to urllib2 requests """ 26 | # add headers to requests 27 | def http_request(self, req): 28 | req.add_header("Accept-Encoding", "gzip, deflate") 29 | return req 30 | 31 | # decode 32 | def http_response(self, req, resp): 33 | old_resp = resp 34 | # gzip 35 | if resp.headers.get("content-encoding") == "gzip": 36 | gz = GzipFile( 37 | fileobj=StringIO(resp.read()), 38 | mode="r" 39 | ) 40 | resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code) 41 | resp.msg = old_resp.msg 42 | # deflate 43 | if resp.headers.get("content-encoding") == "deflate": 44 | gz = StringIO( deflate(resp.read()) ) 45 | resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code) # 'class to add info() and 46 | resp.msg = old_resp.msg 47 | return resp 48 | 49 | # deflate support 50 | import zlib 51 | def deflate(data): # zlib only provides the zlib compress format, not the deflate format; 52 | try: # so on top of all there's this workaround: 53 | return zlib.decompress(data, -zlib.MAX_WBITS) 54 | except zlib.error: 55 | return zlib.decompress(data) 56 | -------------------------------------------------------------------------------- /sphinx/_build/html/genindex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 |
11 | 12 | 13 |56 | Please activate JavaScript to enable the search 57 | functionality. 58 |
59 |61 | From here you can search these documents. Enter your search 62 | words into the box below and click "search". Note that the search 63 | function will automatically search for all of the words. Pages 64 | containing fewer words won't appear in the result list. 65 |
66 | 71 | 72 |' + _('Hide Search Matches') + '
') 190 | .appendTo($('#searchbox')); 191 | } 192 | }, 193 | 194 | /** 195 | * init the domain index toggle buttons 196 | */ 197 | initIndexTable : function() { 198 | var togglers = $('img.toggler').click(function() { 199 | var src = $(this).attr('src'); 200 | var idnum = $(this).attr('id').substr(7); 201 | $('tr.cg-' + idnum).toggle(); 202 | if (src.substr(-9) == 'minus.png') 203 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); 204 | else 205 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); 206 | }).css('display', ''); 207 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { 208 | togglers.click(); 209 | } 210 | }, 211 | 212 | /** 213 | * helper function to hide the search marks again 214 | */ 215 | hideSearchWords : function() { 216 | $('#searchbox .highlight-link').fadeOut(300); 217 | $('span.highlighted').removeClass('highlighted'); 218 | }, 219 | 220 | /** 221 | * make the url absolute 222 | */ 223 | makeURL : function(relativeURL) { 224 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; 225 | }, 226 | 227 | /** 228 | * get the current relative url 229 | */ 230 | getCurrentURL : function() { 231 | var path = document.location.pathname; 232 | var parts = path.split(/\//); 233 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { 234 | if (this == '..') 235 | parts.pop(); 236 | }); 237 | var url = parts.join('/'); 238 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1); 239 | } 240 | }; 241 | 242 | // quick alias for translations 243 | _ = Documentation.gettext; 244 | 245 | $(document).ready(function() { 246 | Documentation.init(); 247 | }); 248 | -------------------------------------------------------------------------------- /sphinx/_build/html/_static/underscore.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 0.5.5 2 | // (c) 2009 Jeremy Ashkenas, DocumentCloud Inc. 3 | // Underscore is freely distributable under the terms of the MIT license. 4 | // Portions of Underscore are inspired by or borrowed from Prototype.js, 5 | // Oliver Steele's Functional, and John Resig's Micro-Templating. 6 | // For all details and documentation: 7 | // http://documentcloud.github.com/underscore/ 8 | (function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e\ 746 | <%username%>\ 747 | \ 748 | <%time.delta%>\ 749 |
\ 750 |\ 752 | \ 753 | reply ▿\ 754 | proposal ▹\ 755 | \ 756 | \ 757 | \ 760 |
\ 761 |\ 762 | <#proposal_diff#>\ 763 |\ 764 |
=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, 80 | CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, 81 | g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, 82 | text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, 83 | setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= 84 | h[3];l=0;for(m=h.length;l =0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== 86 | "="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, 87 | h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l ";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& 90 | q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; 91 | if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); 92 | (function(){var g=s.createElement("div");g.innerHTML="";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: 93 | function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q =0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f
0)for(var j=d;j 0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= 96 | {},i;if(f&&a.length){e=0;for(var o=a.length;e -1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== 97 | "string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", 98 | d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? 99 | a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== 100 | 1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"+d+">"},F={option:[1,""],legend:[1,""],thead:[1," ","
"],tr:[2,"","
"],td:[3,""],col:[2,"
"," "],area:[1,""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
"," ",""];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= 102 | c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, 103 | wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, 104 | prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, 105 | this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); 106 | return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, 107 | ""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); 111 | return this}else{e=0;for(var j=d.length;e 0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", 112 | ""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===" "&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= 113 | c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? 114 | c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= 115 | function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= 116 | Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, 117 | "border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= 118 | a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= 119 | a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/
\ 689 | Sort by:\ 690 | best rated\ 691 | newest\ 692 | oldest\ 693 |
\ 694 |\ 698 |
Add a comment\ 700 | (markup):
\ 701 |