Python多线程爬取知乎获赞过千的答案链接

最近因维护微信公众号需要,想用Python自动获取知乎上获赞过千的答案。

于是想到了爬虫,当然一开始做得很简单,仅仅是单线程的爬取。后来发现速度实在太慢,就开发了多线程功能。

关键的地方都加了注释,思想也不复杂,所以直接上代码:

#coding=utf-8
import urllib2,re,os,threading#使用正则匹配出所需部分
def spider(url):
    try:
        #user_agent = {'User-agent': 'spider'}
        r = urllib2.Request(url)
        data=urllib2.urlopen(r).read()
        title_reg = re.compile(r'<title>\s*(.*?)\s*</title>')
        title=re.findall(title_reg,data)[0]
        title=re.findall(r'(.*?) -.* -.*',title)[0].decode('utf-8')#加了decode之后解决中文文件夹名问题
        if not os.path.exists(title):
            vote=map(int,re.findall('data-votecount="(.*?)"',data))#点赞量
            link=re.findall('target="_blank" href="(.*?)"',data)#该回答的链接
            if max(vote)<1000:
                return data
            f=open(title+'.txt','w+')
            for i in range(len(vote)):
                if vote[i]>1000:#若赞数超过一千,则将该答案的链接保存下来
                    f.write('www.zhihu.com'+link[i]+'\n'+str(vote[i])+'赞'+'\n\n')
            f.close()
    except:
        return

def CrawlTopic(topicURL):
    basicURL='http://www.zhihu.com'
    topicURL+='/questions?page='
    filename=topicURL[27:34]+'.txt'#file用来存取每次爬取结束后的页数,因为爬取时间较长,很难一次爬完
    if not os.path.exists(filename):
        f_page=open(filename,'w+')
        f_page.write('1')
        f_page.close()
        page=1
    else:
        f_page=open(filename,'r+')
        page=int(f_page.read())
        f_page.close()
    while 1:
        r1 = urllib2.Request(topicURL+str(page))
        try:
            res=urllib2.urlopen(r1).read()
        except:
            page+=1
            f_page=open(filename,'w+')
            f_page.write(str(page))
            f_page.close()
            continue
        if not res:
            f_page=open(filename,'w+')
            f_page.write(str(page))
            f_page.close()
            continue
        questions=re.findall('<a target="_blank" class="question_link" href="(.*?)">',res)
        print page
        for q in questions:
            spider(basicURL+q)
        page+=1
        f_page=open(filename,'w+')
        f_page.write(str(page))
        f_page.close()

threads = []
topics=[#需要爬取的网页
    'http://www.zhihu.com/topic/19551147',
    'http://www.zhihu.com/topic/19569848',
    'http://www.zhihu.com/topic/19691659',
    'http://www.zhihu.com/topic/19556423',
    'http://www.zhihu.com/topic/19550564',
    'http://www.zhihu.com/topic/19566266',
    'http://www.zhihu.com/topic/19556758',
    'http://www.zhihu.com/topic/19694211'
    ]
for item in topics:
    t = threading.Thread(target=CrawlTopic,args=(item,))
    threads.append(t)#设置多线程对象

for t in threads:
    t.setDaemon(True)
    #将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序会被无限挂起。
    t.start()
    #开始线程活动

t.join()#在子线程完成运行之前,这个子线程的父线程将一直被阻塞。否则父线程一结束就将关闭子线程

爬完之后的结果是这样的
爬取结果

每个txt文件内容如下
txt文件内容

这样就避开了很多无效信息,以后阅读知乎的效率也就高了不少。

### 乎回答多线程爬虫 **模式** 1. 单问题爬取模式 2. 相似问题爬取模式 **输出** ​ **文件名** 问题题目 ​ **文件内容** 1. 问题 2. 问题id 3. 回答者昵称 4. 回答者空间id 5. 回答者id 6. 回答者内容 **单问题爬取模式** **功能** 主要通过用户提供的问题id,爬取单个问题下的所有回答 **相似问题爬取模式** **功能** 通过用户提供的起始问题id,以及相关内容爬取数量,利用乎的**相关问题**进行自动检索,并不断递归至用户提供的爬取数量(默认数量为20)。 **bug** 由于乎具有一定的反爬,所以在相似问题检索时最大的检索量为400,如果到达500就会触发反爬机制,需要用户填写一个验证码才可以继续爬取。(也许未来有时间的话会把取验证码的部分代码补全,但具体机器打码的实现还是太难了,所以还得自己手动输入验证码) **优点** 简单,明了,使用requests库进行爬取,利用递归实现迭代检索,代码量不大。 **缺点** 功能较少,对线程的把握不够好,可能会出现数据少量缺失的情况。 **技术栈:** 1. requests 2. re 3. json 4. time 5. threading **未来** 关于乎的爬取,我这里还有一个存货——爬取乎文章中的表情包(gif,png,jpg),这样就可以愉快的收集表情包了。同时我也尝试着去做了一下对乎用户数据的爬取,但还为成功。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值