6月 05

python 抓取页面

  最初只是简单抓取没有问题,现在要在线上做抓取时发现很多问题。比如:长时间使用报500错误,需要cookie,有的网站有gzip压缩。本段代码已经解决以上问题,但是字符集问题没有处理,因为我要抓的页面没字符问题。我将代码放在tornado上跑,分析的服务器请求后直接抓取返回信息给分析的服务器。

import urllib2
import cookielib

def get_url_context(_url):
    # cookie
    cj = cookielib.CookieJar()
    _myopener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
    _req = urllib2.Request("http://%s" % _url)
    # add head
    _req.add_header("Accept-Language", "zh-cn")
    _req.add_header("Content-Type", "text/html; charset=utf-8")
    _req.add_header("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.1.4322)")
    # open
    _get_page_data = _myopener.open(_req)
    _get_headers = _get_page_data.info()
    _get_rawdata = _get_page_data.read()
    _get_page_data.close()
    # check gzip
    if ('Content-Encoding' in _get_headers and _get_headers['Content-Encoding']) or \
        ('content-encoding' in _get_headers and _get_headers['content-encoding']):
        import gzip
        import StringIO
        data = StringIO.StringIO(_get_rawdata)
        gz = gzip.GzipFile(fileobj=data)
        _get_rawdata = gz.read()
        gz.close()
    return _get_rawdata

get_page测试代码

5月 29

post数据到golang服务和python的pypy服务后数据入库库效率测试

  在测试go语言和pypy接收post参数后,数据入库的效率。服务器使用阿里云的基础服务器,512内存单核CentOS6.3 64位服务器。测试还有上传文件部分。此处只列出了部分代码。
  python使用tornado在pypy1.9环境,python代码没有列出。
  go语言代码如下。数据库配置部分写成可以全局调用的。

package main

import (
	"fmt"
        "database/sql"
        _ "github.com/go-sql-driver/mysql"
	"net/http"
)

func mydb()*sql.DB {
    //配置数据库连接地址
    db, e:= sql.Open("mysql", "test:1111111@tcp(192.168.1.130:3306)/test?charset=utf8")
    checkErr(e)
    fmt.Println(db)
    return db
}

func checkErr(err error) {
    if err != nil {
        panic(err)
    }
}

func IndexHandler(w http.ResponseWriter, r *http.Request) {
        //用于获取插入数据的表id
        var get_id string
	if r.Method == "POST" {
            r.ParseForm()
	    //获取获得的参数
	    get_time:=r.FormValue("time")
            get_mac:=r.FormValue("mac")
            get_md5:=r.FormValue("md5")
	    //插入数据
            stm, e := mydb().Prepare("INSERT INTO `video` set mac=?, md5=?, createDate=?")
            checkErr(e)
            result,e:=stm.Exec(get_mac, get_md5, get_time)
            checkErr(e)
	    //获取插入后数据的id
            id,e:= result.LastInsertId()
            checkErr(e)
	    //返回给客户
            get_id = fmt.Sprint(id)
            context := "Insert id:" + get_id
	    w.Write([]byte(context))
        }
}

func main() {
     http.HandleFunc("/", IndexHandler)
     http.ListenAndServe(":8899", nil)
}

  测试结果:单进程情况下,go语言的速度比pypy的稍慢,基本持平相差不到5%。但是go使用内存量占到45%,cpu使用8%左右。pypy使用内存20%,cpu使用在5%左右。如果多进程pypy可以启动4个,go只能启动两个。这样pypy比go的处理速去应该快一倍多。java代码也有测试,使用tomcat7,因为逻辑更复杂,所以不能参加对比,粗略估计go会比java快40%。
测试代码

5月 11

CentOS 上安装 pypy,做简单测试

以前没有关注过pypy,但是看到rasperry pi上pypy效果不错,我在服务器上也测试一下。
我的操作系统是CentOS是6.4,64位。直径使用源码安装失败,在网上搜索了一下问题较多并且很麻烦。
还是直接用rpm安装比较好,通过搜索,直接下载对应操作系统的pypy,当前CentOS6的pypy只有1.9版本,并不是最新的2.0,先测试一下。链接如下:
http://pkgs.org/search/?keyword=pypy

下载完rpm包开始安装,大家注意顺序。
# rpm -ivh pypy-libs-1.9-1.el6.x86_64.rpm
# rpm -ivh pypy-1.9-1.el6.x86_64.rpm
# rpm -ivh pypy-devel-1.9-1.el6.x86_64.rpm

还是用之前文中的代码进行测试(http://www.simonzhang.net/?p=1844)。
以后测试可能还经常用到这段代码,所以整理了一下格式,代码非原创。

#-*- coding:utf-8 -*-
# -------------------------------
# Filename:    test.py
# Revision:    1.0
# Date:        2013-05-08 
# Author:      simonzhang 
# Web:         www.simonzhang.net 
# Email:       simon-zzm@163.com 
# -------------------------------


def check(num):
     a = list(str(num))
     b = a[::-1]
     if a == b:
         return True
     return False


def main():
    all = xrange(1,10**7)
    for i in all:
        if check(i):
            if check(i**2):
                print i,i**2


if __name__ == '__main__':
    main()

python 测试结果
real 0m40.657s
user 0m40.622s
sys 0m0.019s

pypy 测试结果
real 0m9.833s
user 0m9.803s
sys 0m0.027s

测试效果,pypy比python快差不多4倍。使用pip直接安装tornado,测试了最简单的导入,查看版本是正常的。
代码:test

5月 09

raspberry pi 测试pypy 切割图片效率

为了方便安装pypy的第三方库,首先安装pip。
$ curl -O http://python-distribute.org/distribute_setup.py
$ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py
$ sudo pypy distribute_setup.py
$ sudo pypy get-pip.py

首先找了一个3M(3072×2304)的图片,缩小为300×300的大小
脚本:

# -*- coding:utf-8 -*-
# -------------------------------
# Filename:    .py
# Revision:    1.0
# Date:        2013-05-08
# Author:      simonzhang
# Web:         www.simonzhang.net
# Email:       simon-zzm@163.com
# -------------------------------


from PIL import Image


def main():
    get_data = Image.open('test.jpg')
    tmp = get_data.resize((300, 300),)
    tmp.save('test1.jpg', 'JPEG', quality=75)


if __name__ == '__main__':
    main()

在pypy上装PIL
$ sudo /usr/lib/pypy-upstream/bin/pip install PIL

运行脚本报错如下:

File “/usr/lib/pypy-upstream/site-packages/PIL/Image.py”, line 1290, in resize
self.load()
File “/usr/lib/pypy-upstream/site-packages/PIL/ImageFile.py”, line 189, in load
d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
File “/usr/lib/pypy-upstream/site-packages/PIL/Image.py”, line 385, in _getdecoder
raise IOError(“decoder %s not available” % decoder_name)
IOError: decoder jpeg not available

不能调用系统库,之前在处理过这种问题http://www.simonzhang.net/?p=435
但是pypy比较复杂,兼容有问题。直接删除PIL,使用pillow。Pillow基础就是PIL只是兼容性强,更利于推广。
$ sudo /usr/lib/pypy-upstream/bin/pip uninstall PIL

$ sudo /usr/lib/pypy-upstream/bin/pip install pillow

注意必须使用
from PIL import Image

否则会报错
File “/usr/lib/pypy-upstream/site-packages/PIL/Image.py”, line 2020, in open
raise IOError(“cannot identify image file”)
IOError: cannot identify image file

在安装完pillow后没有产生PIL.pth文件,直接手动写一个。
$ sudo vim /usr/lib/pypy-upstream/site-packages/PIL.pth
内容是:PIL。

开始测试

time python cut_pic.py

real 0m2.841s
user 0m2.630s
sys 0m0.200s

time pypy cut_pic.py

real 0m5.144s
user 0m4.870s
sys 0m0.230s

图片产生大小如下
-rw-r–r– 1 pi pi 3588203 5月 8 16:02 test.jpg
-rw-r–r– 1 pi pi 21907 5月 8 16:10 test_pypy.jpg
-rw-r–r– 1 pi pi 21907 5月 8 16:09 test_python.jpg

直接使用python的效果更佳,不清楚原因。之后有版本升级了再做测试。

5月 08

raspberry pi上测试pypy效果

PyPy 2.0 alpha for ARM 发布

官方网页
http://pypy.org/download.html

有专门针对raspberry pi的版本。来简单做个测试。
我这竟还要翻墙下回来。
安装很顺利。
$sudo dpkg -i pypy-upstream_2.0~alpha+arm_armhf.deb

开始测试一下效果,直接到oschina拷贝“ruby太慢的”python版测试一下。

import time
start=time.time()
all=xrange(1,10**7)
def check(num):
    a=list(str(num))
    b=a[::-1]
    if a==b:
        return True
    return False
for i in all:
    if check(i):
        if check(i**2):
            print i,i**2
 
end=time.time()
print end-start

开始测试
直接用python测试
time python test.py
。。。

real 8m13.570s
user 8m3.490s
sys 0m0.560s

使用pypy测试
time pypy test.py
。。。

real 1m45.521s
user 1m44.230s
sys 0m0.150s

结论使用pypy处理运算速度比python高出差不多7倍的效果。