打算好好深入研究下pytho的socket编程,那天看了这篇博文,http://www.apprk.com/archives/146,于是打算学习下,仿写了一下,发现写好还真不容易,中途出现很多问题,果真是看的容易,做起来难啊。
源代码如下:
import socket
import thread
import urlparse
import select
BUFLEN=8192
class Proxy(object):
def __init__(self,conn,addr):
self.source=conn
self.request=""
self.headers={}
self.destnation=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.run()
def get_headers(self):
header=''
while True:
header+=self.source.recv(BUFLEN)
index=header.find('\n')
if index >0:
break
#firstLine,self.request=header.split('\r\n',1)
firstLine=header[:index]
self.request=header[index+1:]
self.headers['method'],self.headers['path'],self.headers['protocol']=firstLine.split()
def conn_destnation(self):
url=urlparse.urlparse(self.headers['path'])
hostname=url[1]
port="80"
if hostname.find(':') >0:
addr,port=hostname.split(':')
else:
addr=hostname
port=int(port)
ip=socket.gethostbyname(addr)
print ip,port
self.destnation.connect((ip,port))
data="%s %s %s\r\n" %(self.headers['method'],self.headers['path'],self.headers['protocol'])
self.destnation.send(data+self.request)
print data+self.request
def renderto(self):
readsocket=[self.destnation]
while True:
data=''
(rlist,wlist,elist)=select.select(readsocket,[],[],3)
if rlist:
data=rlist[0].recv(BUFLEN)
if len(data)>0:
self.source.send(data)
else:
break
def run(self):
self.get_headers()
self.conn_destnation()
self.renderto()
class Server(object):
def __init__(self,host,port,handler=Proxy):
self.host=host
self.port=port
self.server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind((host,port))
self.server.listen(5)
self.handler=handler
def start(self):
while True:
try:
conn,addr=self.server.accept()
thread.start_new_thread(self.handler,(conn,addr))
except:
pass
if __name__=='__main__':
s=Server('127.0.0.1',8080)
s.start()
其实Http代理服务器本身不难,但写出来还是挺费事的,这里就不细说源代码了,很简单。主要说说,我遇到的问题。
一: 我本来只知道,thread.start_new_thread的第一个参数是函数对象,但当我看到上面的博文时,心里一愣,这样也可以,于是我迅速的测试了一下:
import thread
class Hello:
def __init__(self,content):
print content
def cs():
thread.start_new_thread(Hello, ("Hello World",))
if __name__=='__main__':
cs()
我很失望的发现,报了个异常
Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:
一看,我说嘛,第一个参数怎么可以是对象,我呵呵一笑,稍微鄙视了一下作者。于是,我洗洗睡了,第二天,我还是不死心,于是把代码下下来,本地实验了一下,可以的,立马意识到是我2了,于是立马百度。
原来thread模块中,主线程如果比子线程先结束,就会抛出这个异常,所以我们必须让子线程先结束,最简单的方法就是让主线程sleep足够长的时间,至于多长时间,貌似不知道,那到底怎么解决呢?
比较好的解决办法就是,主线程给每个子线程都加一把锁,子线程在结束前将锁释放掉,主线程一直循环检查锁的状态。代码如下:
import thread
class Hello:
def __init__(self,content,lock):
print content
"""
do something
....
At the end,release the lock
"""
lock.release()
def cs():
lock=thread.allocate_lock()
lock.acquire()
thread.start_new_thread(Hello, ("Hello World",lock))
while True:
if not lock.locked():
break
print "lock release"
if __name__=='__main__':
cs()
结果如下:
Hello World
lock release
二.第二个错误就是比较2的了
self.source.send[data]
TypeError: 'builtin_function_or_method' object is unsubscriptable
主要是单词unsubscriptable不认识,呵呵,单词不认识,伤不起啊。
主要意思就是说,内置函数或方法无法拥有下标,你懂的,错的很2很2。
分享到:
相关推荐
**Python网络爬虫实战-Scrapy14-17** 在Python编程领域,网络爬虫是一种常见的数据获取技术,用于自动化地从互联网上提取大量信息。Scrapy是一个强大的Python爬虫框架,它提供了丰富的功能来简化爬虫开发,提高效率...
这时,OCR(光学字符识别)技术可以用于识别验证码,而代理服务器则可以用来绕过IP限制。Python的Tesseract和PyQuery库可用于OCR处理,而Proxies模块则可以管理代理列表。 最后,了解并遵守网站的robots.txt文件和...
2. **反爬虫策略**:网站常采用的反爬措施包括IP限制、User-Agent检测、验证码、滑动验证等,爬虫开发者需要学会如何设置代理IP、修改User-Agent、识别和破解验证码等技巧。 【数据存储与处理】 1. **CSV/Excel...
它通过模拟浏览器发送HTTP/HTTPS请求到服务器,接收返回的HTML或JSON等格式的数据。Python中的requests库是常用的HTTP客户端库,用于发送HTTP请求。 2. **解析HTML与XPath或BeautifulSoup**:在获取网页源代码后,...
### Python分布式爬虫与逆向进阶实战知识点详解 #### 一、课程概述 本课程旨在帮助学习者从零开始构建完整的爬虫知识体系。通过本课程的学习,学员将能够掌握构建可接单级别的项目所需的技能,并能运用热门爬虫框架...
2. 配置本地代理服务器,在本地发起代理请求,通过多个代理服务器分散请求。 三、Session访问限制 网站可能限制同一会话短时间内对同一资源的访问次数。 应对策略: 1. 模拟正常用户的行为,避免过于频繁地访问...
《Python实战:网络爬虫详解》 Python是一种广泛应用于数据科学、机器学习和网络爬虫领域的强大编程语言。网络爬虫是获取大量网络数据的重要工具,尤其在机器学习项目中,高质量的数据集往往是成功的关键。本教程将...
Python通过Redis客户端库与Redis服务器通信。最常用的Python Redis客户端是`redis-py`,这是一个完全实现了Redis协议的Python库。安装可以通过`pip install redis`完成。 **连接Redis** 在Python中,你可以使用`...
在本篇Python爬虫-mast笔记中,我们将深入探讨Python爬虫的基本概念、常用库和实战技巧,帮助你掌握这一强大的数据获取工具。 首先,Python之所以在爬虫领域广泛应用,得益于其简洁明了的语法和丰富的第三方库。...
Python是一种广泛应用于Web开发、数据分析、人工智能和自动化任务的高级编程语言。...这些练习可能涵盖了基础的网页抓取到复杂的反爬策略,从简单的数据解析到大数据量的处理,全面锻炼你的Python爬虫实战能力。
首先,Python爬虫的核心在于模拟浏览器行为,通过发送HTTP请求(GET或POST)到服务器,获取服务器返回的HTML或其他格式的网页内容。在Python中,我们可以使用requests库来实现这一功能。requests库提供了一种简单...
Python爬虫实战是初学者踏入网络数据抓取领域的绝佳起点。这一主题涵盖了Python语言的基础,网络请求,HTML解析,以及如何处理反爬策略等关键知识点。以下是对这些内容的详细阐述: 1. **Python基础**:Python是...
本教程将通过一个具体的实战项目——爬取豆瓣有关张国荣的日记,来深入理解Python爬虫的工作原理和实现方法。 首先,我们需要了解Python爬虫的基本构成。通常,一个简单的爬虫包括以下几个部分:请求(Request)、...
- **使用代理IP**:通过更换IP地址避免被网站封禁。 - **处理验证码**:对于有验证码的网站,考虑使用OCR识别技术或手动输入等方式绕过。 - **遵守robots.txt协议**:确保不抓取禁止爬取的内容,尊重网站规则。 ###...
9. **部署上线**:将应用部署到生产环境,如Apache或Nginx服务器,配置反向代理和静态文件服务。 综上所述,"Python-基于pythondjangoAdminLTE实现的运维devops管理系统"是一个利用Python Django框架和AdminLTE模板...
RabbitMQ是一款强大的开源消息代理和队列服务器,它基于AMQP(Advanced Message Queuing Protocol)协议,被广泛应用于分布式系统中的异步处理、任务队列以及微服务间的通信。随书源码“RabbitMQ实战-随书源码”和...
这个Python实战项目是一个BBS(Bulletin Board System,电子公告板)论坛的源码,它包含了实现论坛功能的各种脚本和可执行文件。这样的项目对于学习Python编程,特别是Web开发技术非常有帮助。以下是对这个项目中...
《Python实现HTTP代理服务器与内容过滤器详解》 在信息技术高速发展的今天,HTTP代理服务器和内容过滤器在网络安全和数据管理中扮演着重要的角色。本文将深入探讨如何使用Python语言来构建这样的系统,并分析其核心...
8. **实战演练**:在Python_Spider-master项目中,你可能看到了一个具体的爬虫示例,通过以上介绍的工具和技术,抓取并解析特定网站的数据。通过实践,你可以更好地理解和掌握这些知识。 总的来说,Python实现简单...