Python操做小結(mysql、txt\json、crontab、http)

        有段時間沒有使用python了,對它的語法有點生疏,花了幾個小時熟悉,期間發現不少小細節不清楚。爲了下次能快速上手,避免重複犯錯,我將python使用過程當中的一些問題在這篇博文中記錄小結一下,主要內容涉及到python操做mysql數據庫,python發送http請求,解析txt文本,解析JSON字符串,crontab執行python腳本,等等。(注:我用的是python2.7版本)python

        爲方便操做,建議在系統環境變量path裏面添加python的安裝路徑,好比個人是D:\Python27。mysql


1、添加第三方模塊module,並導入模塊linux

        在windowns裏面,能夠先下載模塊對應的包文件,放到python默認的模塊文件夾下(./python2.7/Lib/site-packages/)。而後在cmd中進入模塊的解壓文件,執行python setup.py install。(注意:若是事先沒有添加python安裝路徑到環境變量裏,是不能執行這個命令的)android

        在ubuntu裏,以root用戶權限執行 easy_install module_name,即可。sql

        在linux系統裏,執行 sudo yum install module_name,即可。shell

         有些模塊須要下載對應的壓縮包,解壓後進入包下,找到setup.py,執行數據庫

  python#{版本號} setup.py install 進行安裝

        python的腳本文件裏面,能夠導入其餘腳本文件,並引用其中的方法和參數,使用關鍵字import。以下:
json

        import os,glob,sysubuntu

    注意:要想到添加的模塊成功import導入,須要重啓python 的IDLE,不然雖然能夠在cmd命令行成功import,卻不能在IDLE中import,會提示找不到module。windows


2、基礎數據類型和語法

  一、普通變量定義

   python 做爲腳本型語言,對變量的定義很寬鬆,不用爲變量特定申明其類型,相似於jsp頁面中的變量定義,直接是    變量名=...    便可。

    輸出字符和整型變量拼接的內容時,須要把整型轉換成字符型,如

    i=10

    print 'out:'+i   會報錯:TypeError: cannot concatenate 'str' and 'int' objects

須要更改爲:

    print 'out:'+str(i)


  二、數組變量定義

   數組變量定義,在  =  號後面加上中括號,中括號中能夠指定數組長度。如:phoneList = []。往數組中添加值,用的是數組的append()方法;獲取數組某位的值,用: phoneList[index]便可。獲取數組的長度,能夠用 len(List)方法。數組排序方法:phoneList.sort()

    對數組使用  sorted(array),能直接排序數組。若是是字符串類型,則按首字母排序,如:1, 10, 12, 2, 23, 3 ...


   三、字典變量的定義

(1)字典定義

dict={}  便可。

獲取字典的全部Kye值:    dict.keys()

根據key值取字典value:    v=name_dict[key]

判斷某個key是否在字典裏:

a={'a':1,'b':2,'c':3}
if 'b' in a:
    print a['b']

(2)字典排序

按value值大小排序:

ret_list = sorted(d.items(),key=lambda item:item[1])

d.items()表示將字典d轉換成元組列表,key=lambda item:item[1] 表示選取每一個元組中第二個元素做爲比較對象。此時返回的結果是一個元組列表


  四、字符串變量

   字符串對象包含了一些私有的方法,如

    (1)以某類分隔符對字符串進行分割的 .split(';') 方法;去除字符串首位的字符的 .strip('--')方法;

    (2)截取字符串一段:sStr1 = sStr2[0:n]

    (3)str類型字符串與unicode類型字符串轉換

string和unicode都有decode()和encode()方法。
decode方法是將string轉換成unicode;
encode方法是將unicode轉換成string;
contentList = " ".join([i for i in jieba.cut(contents)])#unicode類型

print contentList.__class__
contentList = contentList.encode('utf-8')
print contentList.__class__



    五、異常處理

    python可使用try...except處理異常,例如:

   

sql='select * from table'
try:
    cur.execute('set NAMES utf8')
    cur.execute(sql)
    con.commit()
except Exception, e:
    print Exception,":",e
    print sql



    六、python文件頭申明

#!/usr/bin/python
#-*- coding:utf-8 -*-
#encoding=utf-8
import os,sys
reload(sys)
sys.setdefaultencoding("utf-8")



    七、對象聲明和使用

#定義對象
class LoginObj:
    app_id=''
    corp_id=''
    corp_name=''
    phone=''
#對象使用
    loginObj=LoginObj()
    loginObj.corp_id='aaa'
    ...

  判斷NoneType類型的數據: if st is None: print("st is none")

NoneType類型數據不能用len(st)==0 或 st=='' 來判斷。



3、讀取數據庫表

  一、引入MySQLdb包。

    windows下,下載這個包的exe文件,直接點擊安裝便可;

    linux下,能夠用命令sudo yum install MySQL-python 安裝。

    引入包:import MySQLdb as mdb         

    MySQLdb鏈接mysql數據庫,只在2.x版本中支持,推薦使用2.7版本。


  二、鏈接mysql數據庫

   須要指定數據庫服務器地址ip、數據庫用戶名和祕密、需訪問的數據庫名以及默認字符編碼。如:

conn = mdb.connect('hostIp','root','view','db_test',charset='utf8')  表示訪問hostIp中的db_test數據庫,用戶名root,密碼view,設置字符編碼是utf8。

        因爲mysql默認數據庫服務器端口是3306,若是你的端口不是這個,就須要在鏈接時指定端口(端口號是int 型,不需加引號),如:

conn = mdb.connect('hostIp','user_name','password','db_name',port,charset='utf8')


  三、使用遊標,來獲取數據庫查詢結果的每一行

   cur = conn.cursor()  #先定義一個遊標

   sql = "select ..."  #定義sql語句

   cur.execute("set NAMES utf8")  #設定sql語句中的參數的字符編碼是utf8

   cur.execute(sql)   #執行sql查詢語句。

   conn.commit()     #提交sql語句,必定要加上。


  四、獲取查詢結果中的每一行結果數據

   rows  = cur.fetchall()  #rows是不少行的一個集合

   val = row[0]  #row 是rows中的一行。使用循環獲取每一行。


4、for循環語句, 子語句必需要縮進一個tab鍵。

   退出循環時,語句與for語句塊間隔一行以方便區分。以下:

for row in rows:

    print (row[0])


print ("out of for block")


5、操做文件

        一、文件路徑,以下:

           windows中: path=r'E:\tmp-excel'+'\\'   (字符串前的字母‘r’的意思,表示一個原始字符串)

        Linux中:file_path='/usr/local/test/'

        對於最後一個路徑字符串以  \  結尾的,須要使用轉義字符形式 '\\',第一個 \ 是轉義標識符,表示接下來的一個字符是真實字符。


        二、讀取路徑下的文件和內容,須要導入 os包和glob包。

        python使用 os.chdir(path) 跳轉到指定path目錄下;

        而後用 glob.glob('*.txt.???'),模糊匹配文件名知足  *.txt???  格式的文件(*號表示匹配任意個字符,?號表示匹配單個任意字符),並返回文件名的數組對象fileList

        使用  fo = open(fileName) 方法打開文件, lines = fo.readlines() 按行讀取文件所有內容。(ps: 雖然我每行都以 '\r' 字符結尾的,但python可能會將整個文件內容只做爲一行,我就是這種狀況。)爲了得到每一行的數據,我將整個一行用 .split('\r') 進行拆分,再進行處理。

        若是須要對路徑下的文件排序後再處理,能夠直接使用數組排序方法fileList.sort(), 對文件名數組排序。


    三、更改文件名

    os.rename(oldName,newName)


6、提交http請求:

(1)使用httplib2提交http GET請求,並獲取響應數據

import httplib2
url=' httplib2.Http('.cache')#設置使用緩存
h=httplib2.Http()#不使用緩存response,content=h.request(url)
print '%s' %(content)


(2)使用httplib提交http POST請求,並獲取響應數據

import httplib
def postToNewUser(userJArray,host,port,url,token):
   headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8','Authorization':'Bearer '+token,'Accept':'application/vnd.yiqiapp-cn.v1+json','User-Agent':'yiqiapp/android/1.0'}
   conn=httplib.HTTPConnection(host,port)
   jparam=urllib.urlencode({'action':'import','users':userJArray})
   conn.request('POST',url,jparam,headers)
   rsp=conn.getresponse()
   data=rsp.read()
   param=json.loads(data)
   return param


注:

    對於包含漢字、空格和其餘特殊字符的URL,須要進行編碼,使用urllib.quote(param)能夠對指定的參數單獨編碼,如:

urllib.quote('2016-08-01 00:00:00')將時間字符串編碼成:2016-08-01%2000%3A00%3A00

 post請求中的參數,使用urllib.urlencode(...)進行封裝成標準格式。 


7、python解析json數據

#導入模塊:json
import json
import httplib2
url='http://api.umeng.com/apps?auth_token=fdsfsdolnmjfsolf'  
h=httplib2.Http('.cache') 
response,content=h.request(url) 
#s是一個數組:[{appkey:xxxx,category:aaaa,name:ddd},{appkey:eee,category:bd,name:kkk}...] 
s=json.loads(content) 
print len(s) 
for i in s: 
    print i['appkey']
#json數組操做
import demjson
jvalueList=[]
jsonArray=[]
jsonObj={}
jsonObj['name']=user.name
jsonObj['phone']=user.phone
try:
    jsonArray.append(jsonObj)
except Exception , e:
    print 'continue'
#print jsonArray[0]['name']
try:
    #將json數組轉換成字符串,去掉'u'標記
    jvalue=demjson.encode(jsonArray)
    jvalueList.append(jvalue)
    userNum=userNum+1
except Exception , e:
    print jvalue



8、在crontab中定時執行python腳本

    1. crontab執行定時任務的方法,我就不作過多說明了,就是指定定時執行的時間、需執行的腳本命令。舉個例子,天天8點50分,執行日誌解析的腳本,將結果保存到指定文件中:

    50 8 * * * /usr/local/bin/python   /root/python_scripts/parse_log.py > /root/results/test.txt &

    2. 可能會出現的問題

    (1)一個最可能出現的問題就是,上面的語句[/usr/local/bin/python /root/python_scripts/parse_log.py > /root/results/test.txt &] 在shell中執行沒有問題,可是在crontab中卻不能執行,並可能提示某些依賴的module沒法導入:importError: No module named ....

      產生這個問題的最可能的緣由是,crontab和shell中執行python時的版本不一致。咱們能夠經過一下方法進行驗證:

      首先,在shell中執行:import sys,而後執行print sys.path,從系統路徑當中找到當前shell使用的python版本。

['', '/usr/local/lib/python2.7/site-packages/setuptools-12.0.5-py2.7.egg', '/usr/local/lib/python2.7/site-packages/gunicorn-19.1.1-py2.7.egg'......

      而後,在parse_log.py中加入import sys  和  print sys.path 兩行,在crontab中設定定時任務,如舉例中的語句。執行結果可能會以下:

['', '/usr/local/lib/python2.6/site-packages/setuptools-12.0.5-py2.6.egg', '/usr/local/lib/python2.6/site-packages/gunicorn-19.1.1-py2.6.egg'......

      咱們發現crontab和shell執行python時引用的版本不一致,而提示沒法加載的模塊可能在某個版本以後才新增進來的,所以出現了沒法加載模塊的問題。

    那麼,解決的方法是:在crontab中使用全路徑指定引用的python版本,即:

50 8 * * * /usr/local/bin/python2.7 /root/python_scripts/parse_log.py > /root/results/test.txt &


      須要說明的是,爲避免這類問題的出現,咱們在設置crontab定時任務時,最後都使用全路徑。   




代碼示例:

此次寫的的代碼以下:

1、讀取txt文件

#!/usr/bin/python
#coding=utf-8
# -*- coding: utf-8 -*-
import os,glob,sys
phoneList = []
path=r'E:\tmp-excel'+'\\'
os.chdir(path)
sumJ=0
for fname in glob.glob('*.txt'):
    fo=open(fname)
    lines=fo.readlines()
    j=0
    print (fname)
    for line in lines:        
        line=line.split('\r')
        for l in line:
            l=l.split(',,')
            phoneList.append(l[1])
            #print (l[1])
            j=j+1
    print (j)
    sumJ=sumJ+j
    print ("total phoneNo is :",len(phoneList))
print ("total phoneNo is :",sumJ)
相關文章
相關標籤/搜索