文的文字及圖片來源於網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯系我們以作處理。
作者:Huangwei AI
來源:Python與機器學習之路
PS:如有需要Python學習資料的小伙伴可以加點擊下方鏈接自行獲取
http://note.youdao.com/noteshare?id=3054cce4add8a909e784ad934f956cef
最近小編經常刷知乎上的一個問題“你見過哪些是「以為是個王者,結果是個青銅」的視頻或圖片?”。從這個問題我們就已經可以看出來里面的幽默成分了,點進去看果然是笑到停不下來。於是,我想一個個點進去看,還不如把這些視頻都下載下來,享受一頓爆笑。
獲取url
我們使用Google瀏覽器的“開發者工具”獲取網頁的url,然后用requests.get函數獲得json文件,再使用json.loads函數轉換成Python對象:
1 url = "https://www.zhihu.com/api/v4/questions/312311412/answers?include=data%5B%2A%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_labeled%3Bdata%5B%2A%5D.mark_infos%5B%2A%5D.url%3Bdata%5B%2A%5D.author.follower_count%2Cbadge%5B%2A%5D.topics&limit=20&offset="+str(i*20)+"&platform=desktop&sort_by=default" 2 r = requests.get(url,headers = kv) 3 dicurl = json.loads(r.text)
獲取content
我們使用谷歌瀏覽器的一個開發者工具JSONview,可以看到打開的url中有一個content,這里面就是我們要找的回答內容,視頻url也在里面。將返回的json轉化成python對象后,獲取其中content里面的內容。也就是說,我們獲得了每一個回答的內容,包括了視頻的地址。
1 for k in range(20):#每條dicurl里可以解析出20條content數據 2 name = dicurl["data"][k]["author"]["name"] 3 ID = dicurl["data"][k]["id"] 4 question = dicurl["data"][k]["question"]["title"] 5 content = dicurl["data"][k]["content"] 6 data_lens = re.findall(r'data-lens-id="(.*?)"',content)
獲得視頻地址
打開獲取的content,找到href后面的url,打開看一下打開后視頻正是我們要的內容,但是發現url不是我們獲取的真實地址。仔細觀察后發現,這個url發生了跳轉。想要知道如何跳轉來的,我們再次F12,打開開發者工具,發現請求了一個新的URL。觀察發現,其實后面一串數字就是之前的data-lens-id。
對這個地址進行構造:
1 videoUrl = "https://lens.zhihu.com/api/v4/videos/"+str(data_lens[j]) 2 R = requests.get(videoUrl,headers = kv) 3 Dicurl = json.loads(R.text) 4 playurl = Dicurl["playlist"]["LD"]["play_url"] 5 #print(playurl)#跳轉后的視頻url 6 videoread = request.urlopen(playurl).read()
完成之后,我們就可以下載視頻了。
完整版代碼:
1 from urllib import request 2 from bs4 import BeautifulSoup 3 import requests 4 import re 5 import json 6 import math 7 def getVideo(): 8 m = 0#計數字串個數 9 num = 0#回答者個數 10 path = u'/home/zhihuvideo1' 11 #path = u'/home/zhihuimage' 12 kv = {'user-agent':'Mozillar/5.0'} 13 for i in range(math.ceil(900/20)): 14 try: 15 url = "https://www.zhihu.com/api/v4/questions/312311412/answers?include=data%5B%2A%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_labeled%3Bdata%5B%2A%5D.mark_infos%5B%2A%5D.url%3Bdata%5B%2A%5D.author.follower_count%2Cbadge%5B%2A%5D.topics&limit=20&offset="+str(i*20)+"&platform=desktop&sort_by=default" 16 r = requests.get(url,headers = kv) 17 dicurl = json.loads(r.text) 18 for k in range(20):#每條dicurl里可以解析出20條content數據 19 name = dicurl["data"][k]["author"]["name"] 20 ID = dicurl["data"][k]["id"] 21 question = dicurl["data"][k]["question"]["title"] 22 content = dicurl["data"][k]["content"] 23 data_lens = re.findall(r'data-lens-id="(.*?)"',content) 24 print("正在處理第" + str(num+1) + "個回答--回答者昵稱:" + name + "--回答者ID:" + str(ID) + "--" + "問題:" + question) 25 num = num + 1 # 每次碰到一個content就增加1,代表回答者人數 26 for j in range(len(data_lens)): 27 try: 28 videoUrl = "https://lens.zhihu.com/api/v4/videos/"+str(data_lens[j]) 29 R = requests.get(videoUrl,headers = kv) 30 Dicurl = json.loads(R.text) 31 playurl = Dicurl["playlist"]["LD"]["play_url"] 32 #print(playurl)#跳轉后的視頻url 33 videoread = request.urlopen(playurl).read() 34 35 fileName = path +"/" + str(m+1) + '.mp4' 36 print ('===============================================') 37 print(">>>>>>>>>>>>>>>>>第---" + str(m+1) + "---個視頻下載完成<<<<<<<<<<<<<<<<<") 38 videoname = open(fileName,'wb') 39 40 videoname.write(videoread) 41 m = m+1 42 except: 43 print("此URL為外站視頻,不符合爬取規則") 44 except: 45 print("構造第"+str(i+1)+"條json數據失敗") 46 47 if __name__ == "__main__": 48 getVideo()
跑這個程序需要注意的是需要按照代碼存儲視頻的路徑建立一個文件夾:
結果
經過一段時間爬蟲,我們最終獲得了七百多條視頻: