Python多執行緒爬取知乎獲贊過千的答案連結

shallowlearning發表於2015-08-10

最近因維護微信公眾號需要,想用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檔案內容

這樣就避開了很多無效資訊,以後閱讀知乎的效率也就高了不少。

相關文章