標籤:cookie 爬蟲 微博 多線程 python
讀取cookies 可以這樣:
filename=‘FileCookieJar.txt‘
ckjar = cookielib.MozillaCookieJar()
#這裡讀取cookie
ckjar.load(filename, ignore_discard=True, ignore_expires=True)
for item in ckjar:
print "name:" +item.name
print "Value:"+item.value
訪問頁面後,cookies 有變化,得到了新的cookies 值
ckproc = urllib2.HTTPCookieProcessor(ckjar)
opener = urllib2.build_opener(ckproc)
f = opener.open(req)
htm = f.read().decode(‘utf-8‘)
for item in ckjar:
print "name:" +item.name
print "Value:"+item.value
寫入cookies 注意,要在串連關閉前寫入
ckjar.save(filename,ignore_discard=True, ignore_expires=True)
f.close()
ignore_discard的意思是即使cookies將被丟棄也將它儲存下來,
ignore_expires的意思是如果在該檔案中cookies已經存在,則覆蓋原檔案寫入,
在這裡,我們將這兩個全部設定為True。
這裡如果加入了cookie 的話 可能認證方面就要多考慮一些了。因為,手機微博.cn 是可以用cookies 登陸的
所以,和可能如果不記錄cookie的話每次都登陸的流程,就要變得複雜一些,如果第一驗證就用cookies 通過了的話就不用再類比登陸了
判斷檔案存在與否,用:os.path.exists(filename)
判斷特定gsid 欄位是否沒有出現在cookies檔案裡,用: if(not("gsid_CTandWM" in str(ckjar))):
如果不存在就是要登陸,否則就可以直接開始調用爬取的方法了
這裡WeibocCatch 是另外一個類:我可以這樣調用裡面函數:WeiboCatch.findweibo(htm)
#為什麼可以不用初始化對象就可以直接通過類名調用方法,當然是不可以的,啟動並執行時候就會報錯
#(這個錯誤很隱蔽,在編碼過程中並不會報錯,因為python是解釋執行的
#在運行過程中就會找不到這個方法。
#解決方式,要麼執行個體化對象後再調用方法,要麼用“類方法”即在類名上加上@classmethod 修飾
#並且要把方法的第一個預設參數寫成cls)這裡我採用第二種方法,在類名上加修飾符
WeiboCatch.findweibo(htm)
這個findweibo方法就要這樣定義:
#類方法,用classmethod來進行修飾
@classmethod
def findweibo(cls,sweb):法就要這樣定義
這個cls 不是self 的“變種”哦。千萬不要認為就是self的用法,self和cls 還是有很大不同的
這裡我要爬取的是微博內容和朋友(他關注的人,主動,興趣強烈)關係而不是(關注他的人,粉絲,被動,幹擾太多)
這裡有兩個方法,一個catchfollow 和一個catchprofile
方法大體規則都一樣,就是最後需要抽取的內容和處理方式不同。寫到兩個方法裡。
想著這樣應該可以用兩個線程同時去做。
obj=WeiboCatch()
threads = []
#這裡這個逗號不要少了,參數格式(target=function, args=(, kwargs))
#第二個參數是傳遞給線程函數的參數,它必須是tuple類型,kwargs是選擇性參數
t1 = threading.Thread(target=obj.catchprofile,args=(weibofollow,))
threads.append(t1)
t2 = threading.Thread(target=obj.catchfollow,args=(weiboporfile,))
threads.append(t2)
for t in threads:
t.setDaemon(True)# 設定守護進程(後台進程),threading模組的線程setDaemon就是為瞭解決這個問題的,
#如果setDaemon(True),那麼和之前一樣,主線程結束,所有子線程都將結束。
#如果setDaemon(False),主線程將等待該線程結束,等同於你調用線程的join方法。
t.start()
t.join() # 父線程必須要等待子線程執行完成才能在繼續執行
print "task is all over "
threading.Thread類的使用:
1,在自己的線程類的__init__裡調用threading.Thread.__init__(self, name = threadname)
Threadname為線程的名字
2, run(),通常需要重寫,編寫代碼實現做需要的功能。
3,getName(),獲得線程對象名稱
4,setName(),設定線程對象名稱
5,start(),啟動線程
6,join([timeout]),等待另一線程結束後再運行。主線程A中,建立了子線程B,並且在主線程A中調用了B.join(),
那麼,主線程A會在調用的地方等待,直到子線程B完成操作後,才可以接著往下執行,那麼在調用這個線程時可以使用被調用線程的join方法。
換句話說:如果一個線程A在執行的過程中需要等待另一個線程tB執行結束後才能啟動並執行話,那就可以在A在調用B的B.join()方法,另外還可以給join()傳入等待的時間。
線程對象的setDaemon()方法可以讓子線程隨著主線程的退出而結束,不過注意的是setDaemon()方法必須線上程對象沒有調用start()方法之前調用
(預設情況下,在python中,主線程結束後,會預設等待子線程結束後,主線程才退出)。
7,setDaemon(bool),設定子線程是否隨主線程一起結束,必須在start()之前調用。預設為False。
8,isDaemon(),判斷線程是否隨主線程一起結束。
9,isAlive(),檢查線程是否在運行中。
如果不設定為守護線程程式會被無限掛起。守護進程就是後台進程的意思
子線程啟動後,父線程也繼續執行下去,當父線程執行完最後一條語句後,沒有等待子線程,直接就退出了,同時子線程也一同結束。
同步資料用“鎖”機制,代碼例子如下
while True:
mylock.acquire() #Get the lock
# Do something to the shared resource
print ‘Thread %s locked! num=%s‘%(name,str(num))
if num >= 5:
print ‘Thread %s released! num=%s‘%(name,str(num))
mylock.release()
thread.exit_thread()
num+=1
print ‘Thread %s released! num=%s‘%(name,str(num))
mylock.release() #Release the lock.
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
python 爬蟲2 介紹一下怎麼抓取cookies,python多線程