Category Archives: PHP & Python & etc

CentOS安装Memcached

CentOS原有的yum源里面没有Memcached这个包,我选择安装21andy的repo(包含了Memcached).

# vi /etc/yum.repos.d/centos.21andy.com.repo

放入如下内容

[21Andy.com]
name=21Andy.com Packages for Enterprise Linux 5 - $basearch
baseurl=http://www.21andy.com/centos/5/$basearch/
enabled=1
gpgcheck=0
protect=1

然后

yum install -y memcached

然后自动在/etc/init.d/就生成了memcached启动配置文件. 使用/sbin/chkconfig –list 就能看到memcached的选项了,如果想把memcached开机启动的话 /sbin/chkconfig memcached on 即可.

不喜欢安装”山寨”yum源的话,可以直接下载Memcached官方网站的包

wget http://memcached.googlecode.com/files/memcached-1.4.5.tar.gz

然后解压,配置:

tar -xzvf memcached-1.4.5.tar.gz
cd memcached-1.4.5
./configure –with-libevent=/usr/
make
make install
memcached -l 192.168.10.60 -d -p 11212 -u nobody -m 1024

上面的命令中-d表示用 daemon 的方式启动 memcached,-l和-p组合表示监听在 192.168.10.60 的 11212 端口上(如果不用-p指定端口号,则memcached将运行在11211端口上),-u表示运行用户为 nobody,-m表示为其分配1024MB 的内存。

但是在安装php的memcached扩展的时候,有点犯难了:

yum search memcached
libmemcached.i386 : Client library and command line tools for memcached server
libmemcached-devel.i386 : Header files and development libraries for libmemcached
lighttpd.i386 : Lightning fast webserver with light system requirements
memcached.i386 : High Performance, Distributed Memory Object Cache
memcached-devel.i386 : Files needed for development using memcached protocol
perl-Cache-Memcached.noarch : Perl client for memcached
php-pecl-memcache.i386 : Extension to work with the Memcached caching daemon
php-pecl-memcached.i386 : Extension to work with the Memcached caching daemon
python-memcached.noarch : A Python memcached client library
python-shove.noarch : Common object storage frontend
redis.i386 : A persistent key-value database
rubygem-moneta.noarch : A unified interface to key/value stores

有php-pecl-memcache.i386 和 php-pecl-memcached.i386 两个包,不知道应该安装那个包.但是我安装了前一个包,OK 一切正常.这个版本的php扩展配置文件都在/etc/php.d/里面,有curl.ini mysql.ini之类的外部扩展配置,已经不在php.ini文件里面了.

vi一个memcache的测试文件:

<?php
$memcache = new Memcache;
$memcache->connect('127.0.0.1', 11211) or die ("Could not connect");
$version = $memcache->getVersion();
echo "Server's version: ".$version."\n";
$tmp_object = new stdClass;
$tmp_object->str_attr = 'test';
$tmp_object->int_attr = 123;
$memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");
echo "Store data in the cache (data will expire in 10 seconds)\n";
$get_result = $memcache->get('key');
echo "Data from the cache:\n";
var_dump($get_result);
?>

一切正常.

Django绑定IP

今天在Vmware虚拟机中试着安装了Django,但是开始第一步test project的时候,按照说明运行

python manage.py runserver

因为虚拟机用的是NAT连接,IP地址为192.168.128.129,本机的地址为192.168.128.1,打开浏览器输入http://192.168.128.129:8000/竟然无法访问?!通过netstat查看的确python进程占用了127.0.0.1的8000端口,但是iptables防火墙并没有打开。后来发现时启动runserver的时候需要绑定IP,这样就没有问题了

python manage.py runserver 192.168.128.129:8000

PIL图像处理

1 转换图片格式

>>> import Image
>>> im = Image.open( "sample01.jpg" )
>>> im.save( "fileout.png" )

很聪明的根据后缀名来判断要转换的格式,如果想要保存成和后缀名不同的格式的话:

>>> im.save( "fileout.png", "JPEG" )

这样就忽略的后缀名的格式

2 获取图片大小

>>> import Image
>>> im = Image.open( "sample01.jpg" )
>>> print im.format, im.size, im.mode
JPEG (2288, 1712) RGB

3 批量更改格式

#!/usr/bin/env python

from glob import glob
from os.path import splitext
import Image

jpglist = glob( "python_imaging_pix/*.[jJ][pP][gG]" )

for jpg in jpglist:
    im = Image.open(jpg)
    png = splitext(jpg)[0]+".png"
    im.save(png)
    print png

4 改变图片的品质度

im.save( "quality100.jpg", quality=100 )

5 制作微缩图

>>> im = Image.open( "sample01.jpg" )
>>> print im.size
(2288, 1712)
>>> width = 400
>>> ratio = float(width)/im.size[0]
>>> height = int(im.size[1]*ratio)
>>> nim = im.resize( (width, height), Image.BILINEAR )
>>> print nim.size
(400, 299)
>>> nim.save( "resized.jpg" )

参考:http://tech.seety.org/python/python_imaging.html

Hypy-全文搜索引擎

Hypy 是一个为 Python 应用程序编写的全文搜索引擎,

db = HDatabase()
db.open('casket', 'w')
# create a document object
doc = HDocument(uri=u'http://estraier.gov/example.txt')
# create a search condition object
cond = HCondition(u'lull*')
# get the result of search
result = db.search(cond)
# iterate the result
for doc in result:

[Python]根据相对路径计算绝对路径

例如在抓取过程中,根据网页的绝对地址,链接中有个相对地址,如果才能找到链接的绝对地址?

from urlparse import urljoin
url1 = "http://www.cwi.nl/%7Eguido/Python.html"
url2 = "./FAQ.html"
urljoin(url1,url2)

'http://www.cwi.nl/%7Eguido/FAQ.html'

还有很多不错的URL function在python中。

在读取的过程中经常发现字符串中有换行符或者tab符号,删除比较麻烦,有个很简单的办法

>>> s='''   as asdas \r\nasda'''
>>> s
'   as asdas \r\nasda'
>>> print ''.join(s.split())
asasdasasda

WordPress XML-RPC Python

wordpressLibrary是个Python利用Wordpress XML-RPC协议发布post的lib,使用很方便并且还能发布media,类似图片之类wordpress支持的格式都可以发布。

code:

import wordpresslib
url = 'http://www.mysite.com/wordpress/xmlrpc.php'
wp = wordpresslib.WordPressClient(url, 'username', 'password')
wp.selectBlog(0)
post = wordpresslib.WordPressPost()
post.title = 'Post title'
post.description = 'Post content'
idPost = wp.newPost(post, True)

但是我下载以后,输入正确的url和用户名以及密码后,报错:

raise TypeError, "cannot marshal None unless allow_none is enabled"

后来在wordpresslib.py中第129行稍微改动:

self._server = xmlrpclib.ServerProxy(self.url,allow_none=True)

添加“,allow_none=True”即可。

Python中小tips

有这样一个字符串:z=”3″;m=”4″;k=”2″;l=”9″;d=”0″;b=”5″;i=”7″;w=”6″;r=”8″;c=”1″ 在程序中需要把一部分文本中的字母替换成对应的数字。

首先把字符串中的双引号删除:

str.replace('''"''',"")

'z=3;m=4;k=2;l=9;d=0;b=5;i=7;w=6;r=8;c=1'

str.split(";")

['z=3', 'm=4', 'k=2', 'l=9', 'd=0', 'b=5', 'i=7', 'w=6', 'r=8', 'c=1']

str = dict(k.split("=") for k in str)

{'c': '1', 'b': '5', 'd': '0', 'i': '7', 'k': '2', 'm': '4', 'l': '9', 'r': '8', 'w': '6', 'z': '3'}

一行命令的话:

str = dict(k.split('''=''') for k in str.replace('''"''','''''').split(''';'''))

OK 一个对应完备的dict已经出来了。

在HTMLParser基础上可以定向读取div和排除div

能够读取指定的html内部div,并且能够删除指定div内部无需加载的div内容。
只测试了在指定一个div需要读取,并且在这个div内有一个无需读取的div,并没有做以下情况的测试:
1. 多个div需要读取。
2. 指定div内包含多个无需读取div。
3. 多个指定div内包含一个无需读取div。
等等

#!/usr/bin/python
#-*-coding:utf-8-*-

import re, sys, time
import httplib, os.path as osp
from urlparse import urlparse
import sqlite3 as sqlite
import  HTMLParser


class CustomParser(HTMLParser.HTMLParser):
	#python类中的数据类似于C++中的class static数据,全局通用 节省内存 但是使用的时候指定类名
	selected = ('table', 'h1', 'h2','h3','strong','b','font', 'ul', 'li', 'tr', 'td', 'a','div','p','img')
	#需要抓取的divs,id、name、class属性都可以
	selectedDivIds = ('KonaBody')
	#需要在抓取的层中排除的div,id、name、class属性都可以
	excludeDivIds=('big')
	def reset(self):
		HTMLParser.HTMLParser.reset(self)
		self._level_stack = []
		self._divs_stack = []
		self._exclude_stack = []
		self.text=""
	def handle_starttag(self, tag, attrs):
		if tag == "div":
			if CustomParser.excludeDivIds:
				#如果有 exclude divs 就查找attrs是否为exclude
				ids =  [v for k, v in attrs if k=='id' or k=='name' or k=='class']
				for id in ids:
					if id in CustomParser.excludeDivIds:
							self._exclude_stack.append(tag)
							#print "find exclude"
							return
							
			if CustomParser.selectedDivIds:
				#如果第一个div层已经有了 div内包含的divs都能被读取并且添加到stack中
				if self._divs_stack:
					self._divs_stack.append(tag)
					#print "add tag"
				else:
					#目前stack为空 但是如果div是选取的div 就开始填充stack
					#div的id或者name属性都能作为标识
					ids =  [v for k, v in attrs if k=='id' or k=='name' or k=='class']
					for id in ids:
						if id in CustomParser.selectedDivIds:
								self._divs_stack.append(tag)
								#print "add tag"
								return
		#如果发现在所选取的div中并且_exclude_stack为空
		if self._divs_stack and not self._exclude_stack:
			if tag in CustomParser.selected:
				#整合attrs
				if attrs:
					attrsStr = " ".join(['''%s="%s"''' % (k, v) for k, v in attrs])
					self.text = self.text + "<"+tag+" "+attrsStr+">"
				else:
					self.text = self.text + "<"+tag+">"
	def handle_endtag(self, tag):
		#如果发现在所选取的div中
		if self._divs_stack:
			if tag == 'div':
				if self._exclude_stack:
					self._exclude_stack.pop()
					#print "pop exclude div"
					return
				else:
					self._divs_stack.pop()
					#print "pop include div"
					return
			if tag in CustomParser.selected:
				self.text = self.text + "</"+tag+">"
				
				
		#if tag == "div":
			#if CustomParser.selectedDivIds:
				##div的id或者name属性都能作为标识
				# ids =  [v for k, v in attrs if k=='id' or k=='name' or k=='class']
				# for id in ids:
					# if id in CustomParser.selectedDivIds:
				#self._divs_stack.pop()
			return
	def handle_data(self, data):
		if self._divs_stack:
			if not self._exclude_stack:
				self.text = self.text + data
		return
# ------------------------------------- 开始执行程序 -------------------------------------------


htm = "<html><title>Excel tips</title><body><div id='head'><p>this is a excel tips site.</p></div><div class='KonaBody'><p>first tip:open your excel  software</p><p>clice the <strong>option</strong> button.<img src='excel.jgp'></p><p><div id='big'>444</div> you can get the <a href='tips.htm' alt='excel tips'>tips</a> for your excel.</p></div><p>123</p></body></html>"


p = CustomParser()

p.feed(htm)

print "".join(p.text)

Python映射List

Python的list映射是个不错的tiips,能方便的完成很多操作。

>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}

查找Keys

>>> params.keys()
['server', 'uid', 'database', 'pwd']

查找values

>>> params.values() 
['mpilgrim', 'sa', 'master', 'secret']

keys和values组队List

>>> params.items()  
[('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')]

对dict中的Key和value进行join

>>> ["%s=%s" % (k, v) for k, v in params.items()]
['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']

Python使用HTMLParser技巧-如何处理html中的标签

HTMLParser在处理html文本的时候,默认把一些html标签给删除了,类似“<p>this is a <a href=”#”>link</a>”得到的只有一句话没有链接信息。看到一段代码这样处理:

import  HTMLParser


class CustomParser(HTMLParser.HTMLParser):
	selected = ('table', 'h1', 'h2','h3','strong','b','font', 'ul', 'li', 'tr', 'td', 'a','div','p','img')

	def reset(self):
		HTMLParser.HTMLParser.reset(self)
		self._level_stack = []
		self.text=""
	def handle_starttag(self, tag, attrs):
		if tag in CustomParser.selected:
			#整合attrs
			if attrs:
				attrsStr = " ".join(['''%s="%s"''' % (k, v) for k, v in attrs])
				self.text = self.text + "<"+tag+" "+attrsStr+">"
			else:
				self.text = self.text + "<"+tag+">"
	def handle_endtag(self, tag):
		if tag in CustomParser.selected:
			self.text = self.text + "</"+tag+">"
			return
	def handle_data(self, data):
		self.text = self.text + data
		return

使用stack来保存目前遍历过的tag。