這段時間宅在家裏,被疫情弄得都要發黴了。
爲了打發無聊時光,跟着CSDN上的速成班學了一下Python以及爬蟲。突然發現這玩意也太厲害了,以前只以爲是個獲得數據的工具,現在才發現,這玩意最強悍的是應用在數據篩選和清理。真不愧是現在最火的語言,論代碼的簡介性和麪向對象的友好性上絕不是之前學的那一票面向過程的語言可以比的。要是早知道這玩意,該能省下多少事,唉……我的大好青春……
不說廢話,學完了這幾天的課程,我躍躍欲試,決定活學活用一把,做一個可以爬貼吧的爬蟲:
import urllib.parse as up import urllib.request as ur import lxml.etree as le import operator kw = str(input('請輸入詞條: ')) start_page = int(input('請輸入起始頁面: ')) final_page = int(input('請輸入結束頁面: ')) fin_data = [] Num = 0
首先調模塊,urllib的庫以及lxml的庫都是必須滴~(話說這lxml的庫單裝真不是我等凡人可以搞定的,爲了裝這個龜孫子我又上外網又是找鏡像,最後還是裝不上去。等看完凌晨四點的我知道還有Anaconda這個東西之後只剩下了:*~@*%)
除了調模塊還有輸入聲明,詞條和頁碼單獨拿出來給輸入,這樣想搜啥都行。
for i in range(start_page, final_page+1): pn = i user_data = { 'kw': kw, 'ie': 'utf-8', # 'cid': None, # 'tab': 'corearea', 'pn': str(pn*50-50) } data_url = up.urlencode( user_data ) print('正在檢索第%d頁……' % pn) request = ur.Request('https://tieba.baidu.com/f?'+data_url) # 將url格式粘合後請求頁面 response = ur.urlopen(request).read() # 將頁面導入 # with open('%s.html' % kw,'wb') as f: # f.write(response) html_x = le.HTML(response) # 將url地址轉換成xpath文件 root_path = '//div[@class="t_con cleafix"]' rep_num_path = './div[@class="col2_left j_threadlist_li_left"]/span/text()' # 回覆數地址 title_path = './div[@class="col2_right j_threadlist_li_right "]/div/div/a/text()' # 標題地址 link_path = './div[@class="col2_right j_threadlist_li_right "]/div/div/a/@href' # 鏈接地址 # author_path = './div/div/div/span[contains(@title,"主題作者")]/@title' # 作者地址 creatTime_path = './div/div/div/span[contains(@title,"創建時間")]/text()' # 創建時間地址 # replier_path = './div/div/div/span[contains(@title,"最後回覆人")]/@title' # 最後回覆者地址 replyTime_path = './div/div/div/span[contains(@title,"最後回覆時間")]/text()' # 最後回覆時間地址 # pic_path = root_path + './div/div/div/div/div/div/ul/li/a/img/@bpic' # 圖片地址 # video_path = root_path + './div/div/div/div/div/div/ul/li/div/a/@get_data-video' # 視頻地址 div_x_s = html_x.xpath(root_path) for i,div_x in enumerate(div_x_s): rep_num = (int(div_x.xpath(rep_num_path)[0])) rep_num_s = str(rep_num) title_s = str(div_x.xpath(title_path)[0]) link_s = 'https://tieba.baidu.com' + str(div_x.xpath(link_path)[0]) rep_time_s = '' if div_x.xpath(replyTime_path): rep_time_s = str(div_x.xpath(replyTime_path)[0]).replace('\r\n', '').rstrip().lstrip() else: rep_time_s = 'Notime' cre_time_s = str(div_x.xpath(creatTime_path)[0]) # pic_s = div_x.xpath(pic_path)[0] # video__s = div_x.xpath(video_path)[0] temp_data = { '編號': Num + i, '標題': title_s, '鏈接': link_s, '回覆時間': rep_time_s, '創建時間': cre_time_s, '回帖數量': rep_num } fin_data.append(temp_data) # print(temp_data) Num += len(div_x_s)
這是巨長的主要代碼段(第一次寫,如果有大佬看了不要噴我)
外層for用來重複訪問選定的頁面;
user_data用來保存對應的用戶請求字段,這裏麪包括“kw”、“ie”、“pn”三段
kw:表示訪問詞條;ie:表示訪問的編碼方式;pn:表示訪問的頁碼,百度規則下和實際頁碼對應了個50倍的關係將用戶段定義好之後就開始和初始url粘合,並調用urllib兩個庫將頁面拿下來並導入內存。
然後就是url地址轉換成xpath地址列表,對列表進行檢索。root_path是貼吧每一欄有用信息包含的標籤,剩下的都是在這個標籤下各個有用字段標籤的xpath地址,我把覺得有用的xpath地址都保留了下來,回頭也可以用這些爬圖片視頻什麼的。
在第二個for循環裏對幾個有用的xpath對象進行提取並轉換成字符串在後面寫入fin_data列表保存。其中回帖數量也就是rep_num取回來進行後面排序挑出熱門的帖子。
這裏面有個有意思的就是最後一次回帖時間,經過比較發現並不是每個帖子都有這一項,所以要做一次判斷,如果沒時間就給個“NoTime”。(看了一下基本上就是首頁的幾個置頂帖什麼的)
最後還給每個帖子編了個號,用num記一下現在的檢索總量。
fin_data.sort(key = operator.itemgetter('回帖數量'), reverse= True) print('輸出完成,回覆量最多的5條帖子及鏈接如下:') data_s = '' for i ,value in enumerate(fin_data): data_s += str(value) + '\n' if i == 4: print(data_s) data_s = data_s.encode(encoding='utf-8') with open('%s貼吧熱點.txt' % kw, 'wb') as f: f.write(data_s) print('詳細信息請訪問根目錄,按任意鍵退出。') while input(): break
最後離開循環之後,就是排序了。這個地方排序的關鍵詞選擇用的是operator.itemgetter()這個方法裏調用的函數,它返回的是一個函數,然後這個函數給了key再由sort方法來調。(反正這東西有點玄妙,具體還得研究一下。)
最後就是字符串的生成,爲了好看用個循環把他分段,再用文件流寫到txt文件裏,並打印出前五個熱點文章及地址。
最後的最後,嘗試將這個py文件導出exe文件,這要用到三方包:PyInstaller,具體流程參考這個老哥的文章:https://blog.csdn.net/zwx19921215/article/details/85234801
生成的文件會保存在程序文件同級目錄下的dist文件裏:
打開文件夾,會有一個生成的exe文件,我們打開exe文件,開始運行,按武漢詞條搜索結果如下:
可以看到裏面有最火的五個回覆帖的詳細信息。
剩下的詳細信息可以打開根目錄下的對應txt文件:
打開txt文件可以看到每個帖子的詳細信息:
好的,搞定
明天研究下怎麼在從這些url裏面把詳細文章抓回來
over~