您的位置:首页 > 编程语言 > Python开发

python 爬虫2 介绍一下怎么抓取cookies,python多线程

2015-08-03 20:38 701 查看
读取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()

#注意: join()方法的位置是在for循环外的,也就是说必须等待for循环里的两个进程都结束后,才去执行主进程。

#或者结合flag 和while 来判断 程程是否还有效

#is_alive(): Return whether the thread is alive.

for t in threads:

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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: