이 기사에서는 Python을 사용하여 멀티스레드 HTTP 다운로더를 작성하고 .exe 실행 파일을 생성하는 방법을 소개합니다.
환경: windows/Linux + Python2.7.x
싱글 스레드
멀티 스레드를 도입하기 전에 싱글 스레드를 도입합니다. 첫 번째. 단일 스레드를 작성하는 방법은 다음과 같습니다.
1. URL을 분석합니다.
3. http 요청 패키지를 구성합니다.
4.
사용자 입력 URL로 구문 분석됩니다. 구문 분석된 경로가 비어 있으면 할당된 값은 '/'이고, 포트 번호가 비어 있으면 할당된 값은 "80"입니다. 다운로드된 파일의 파일 이름은 사용자가 원하는 대로 변경할 수 있습니다('y' 입력). 변경 사항을 나타내려면 other를 입력하고, 변경이 필요하지 않음을 나타내려면 other를 입력합니다.
여러 구문 분석 기능은 다음과 같습니다.#解析host和path def analyHostAndPath(totalUrl): protocol,s1 = urllib.splittype(totalUrl) host, path = urllib.splithost(s1) if path == '': path = '/' return host, path #解析port def analysisPort(host): host, port = urllib.splitport(host) if port is None: return 80 return port #解析filename def analysisFilename(path): filename = path.split('/')[-1] if '.' not in filename: return None return filename
웹 서버에 연결
사용 소켓 URL을 파싱하여 얻은 호스트와 포트를 기반으로 웹 서버에 연결하는 모듈입니다. 코드는 다음과 같습니다.
import socket from analysisUrl import port,host ip = socket.gethostbyname(host) s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect((ip, port)) print "success connected webServer!!"
http 요청 패키지
URL을 구문 분석하여 얻은 경로, 호스트 및 포트를 기반으로 HTTP 요청 패키지를 구성합니다.
from analysisUrl import path, host, port packet = 'GET ' + path + ' HTTP/1.1\r\nHost: ' + host + '\r\n\r\n'
파일 다운로드
구성된 http 요청 패키지를 기반으로 서버에 파일을 보내고 응답을 캡처합니다. message 헤더의 "Content-Length"입니다.
def getLength(self): s.send(packet) print "send success!" buf = s.recv(1024) print buf p = re.compile(r'Content-Length: (\d*)') length = int(p.findall(buf)[0]) return length, buf파일을 다운로드하고 다운로드에 걸리는 시간을 계산해 보세요.
def download(self): file = open(self.filename,'wb') length,buf = self.getLength() packetIndex = buf.index('\r\n\r\n') buf = buf[packetIndex+4:] file.write(buf) sum = len(buf) while 1: buf = s.recv(1024) file.write(buf) sum = sum + len(buf) if sum >= length: break print "Success!!" if __name__ == "__main__": start = time.time() down = downloader() down.download() end = time.time() print "The time spent on this program is %f s"%(end - start)
멀티스레딩
응답 메시지 헤더에서 "Content-Length" 필드를 잡아서 결합하세요. 스레드 번호로 섹션별로 잠기고 다운로드됩니다. 단일 스레드와 달리 여기에서는 모든 코드가 하나의 파일로 통합되고 코드에 더 많은 Python 내장 모듈이 사용됩니다.
"Content-Length" 가져오기:def getLength(self): opener = urllib2.build_opener() req = opener.open(self.url) meta = req.info() length = int(meta.getheaders("Content-Length")[0]) return length스레드 수와 결합된 가져온 길이를 기준으로 범위를 나눕니다.
def get_range(self): ranges = [] length = self.getLength() offset = int(int(length) / self.threadNum) for i in range(self.threadNum): if i == (self.threadNum - 1): ranges.append((i*offset,'')) else: ranges.append((i*offset,(i+1)*offset)) return ranges파일에 콘텐츠를 쓸 때 스레드를 잠그고 lock.acquire( )...lock.release 대신 lock과 함께 사용하세요. ( ); 파일 쓰기의 정확성을 보장하기 위해 file.seek()를 사용하여 파일 오프셋 주소를 설정합니다.
def downloadThread(self,start,end): req = urllib2.Request(self.url) req.headers['Range'] = 'bytes=%s-%s' % (start, end) f = urllib2.urlopen(req) offset = start buffer = 1024 while 1: block = f.read(buffer) if not block: break with lock: self.file.seek(offset) self.file.write(block) offset = offset + len(block) def download(self): filename = self.getFilename() self.file = open(filename, 'wb') thread_list = [] n = 1 for ran in self.get_range(): start, end = ran print 'starting:%d thread '% n n += 1 thread = threading.Thread(target=self.downloadThread,args=(start,end)) thread.start() thread_list.append(thread) for i in thread_list: i.join() print 'Download %s Success!'%(self.file) self.file.close()실행 결과:
(*.py) 파일을 ( * .exe) 실행 파일
도구를 작성한 후 Python이 설치되어 있지 않은 사람들이 이 도구를 사용하도록 하려면 어떻게 해야 합니까? 이를 위해서는 .py 파일을 .exe 파일로 변환해야 합니다.
여기에서는 Python의 py2exe 모듈을 사용합니다. 처음 사용하는 것이므로 소개하겠습니다. py2exe는 Python 스크립트를 독립적인 실행 파일로 변환하는 실행 파일입니다. Python을 설치하지 않고도 Windows에서 이 실행 프로그램을 실행할 수 있도록 Windows(*.exe) 도구에 파일을 저장합니다. 다음으로 multiThreadDownload.py와 동일한 디렉터리에 mysetup.py 파일을 만들고 다음과 같이 작성합니다.from distutils.core import setup import py2exe setup(console=["multiThreadDownload.py"])그런 다음 Python 명령을 실행합니다. mysetup.py py2exe는 dist 폴더를 생성하고 multiTjhreadDownload.exe 파일이 그 안에 있습니다. 클릭하여 실행하세요.
데모 다운로드 주소: HttpFileDownload_jb51.rar
위 내용은 이 글의 전체 내용입니다. 모든 분들의 학습에 도움이 되길 바라며, PHP 중국어도 지원해 주시길 바랍니다. 웹사이트.