前言
今天某小麗同學來找我,有個實驗需要用到輕鬆籌的數據進行一個分析。可是沒有足夠的數據,如何辦是好?
樂於助人的我,當然不會置之不理~
(ps.畢竟是小姐姐嘛,拒絕了不好,對叭)
於是乎,我抄起傢伙,說幹就幹。
一、爬蟲分析
通過簡單的分析,可以發現輕鬆籌提供了一個接口,可以返回某個項目的相關數據,具體如下:
地址如下,xxxxxx表示項目的UUID:
<code>https://gateway.qschou.com/v3.0.0/project/index/text3/xxxxxx /<code>
- 1
也就是說,我們只要有UUID,那麼就可以通過requests發送請求很容易就能得到數據。這還不簡單,我們對UUID進行遍歷不就行了嘛?
然而,UUID的長度為32位,要是想遍歷的話,等明年去叭…
解決問題(小聲說:“獲得小姐姐的青睞”)的關鍵就是想辦法找到項目的UUID。
二、爬取項目ID
在官網搜尋了一番,並沒有發現哪裡有UUID。於是,我們只能另闢蹊徑。最後,我決定從百度貼吧入手,搜索相關的帖子,並把帖子中的項目鏈接中的UUID提取出來。
1.抓取帖子的URL
遍歷整個“輕鬆籌吧”,抓取每個帖子的URL:
<code>url_tieba = 'https://tieba.baidu.com/f?kw=輕鬆籌&ie=utf-8&pn=%d' # 貼吧頁面,pn=0,50,100... p_href = 'href="/p///p2.ttnews.xyz/5fea2e730216c7e617fd375e.jpg"' hrefs = [] for i in range(1): # 爬取的頁數 try: pn = i*50 res = requests.get(url_tieba%pn) html = res.text list_herf = re.findall(p_href,html) for h in list_herf: hrefs.append('https://tieba.baidu.com/p/'+h) print('第%d頁獲取成功'%(i+1)) except: pass with open('tiezi_url.txt','w') as f: for h in hrefs: f.write(h+'\n') /<code>
2.提取帖子中的UUID
要獲取每個帖子裡面的項目UUID,主要有兩種方式:
(1)從帖子中的鏈接中提取
首先定義匹配鏈接的正則表達式:
<code>p_projuuid = 'https://m2.qschou.com.*?projuuid=//p2.ttnews.xyz/5fea2e730216c7e617fd375e.jpg&' /<code>
- 1
對帖子進行匹配:
<code>for h in hrefs: try: res = requests.get(h) html = res.text list_projuuid = re.findall(p_projuuid,html) # 判斷帖子裡是否有直接的鏈接 if len(list_projuuid) != 0: for p in list_projuuid: if p not in projuuids and len(p) == 36: projuuids.append(p) print('%s 提取到projuuid:%s'%(h,p)) else: # 提取帖子中的圖片獲取二維碼 list_img = re.findall(p_img,html) if len(list_img) == 0: print('%s 無法提取到projuuid'%h) else: for i in list_img: txt_list = get_ewm(i) if len(txt_list) != 0: barcodeData = txt_list[0].data.decode("utf-8") for p in re.findall('projuuid=(.*)',barcodeData): if p not in projuuids and len(p) == 36: projuuids.append(p) print('%s 提取到projuuid:%s'%(h,p)) except: pass /<code>
(2)從帖子中的二維碼中提取
首先,我們得匹配帖子中的所有圖片,正則如下:
<code>p_img = 'class="BDE_Image" class="lazy" src="//p2.ttnews.xyz/loading.gif" data-original="//p2.ttnews.xyz/5fea2e730216c7e617fd375e.jpg"' /<code>
- 1
然後對其中的每張圖片,進行二維碼讀取,如果包含項目連接則將其中的UUID提取出來:
<code>for h in hrefs: try: res = requests.get(h) html = res.text list_projuuid = re.findall(p_projuuid,html) # 判斷帖子裡是否有直接的鏈接 if len(list_projuuid) != 0: for p in list_projuuid: if p not in projuuids and len(p) == 36: projuuids.append(p) print('%s 提取到projuuid:%s'%(h,p)) else: # 提取帖子中的圖片獲取二維碼 list_img = re.findall(p_img,html) if len(list_img) == 0: print('%s 無法提取到projuuid'%h) else: for i in list_img: txt_list = get_ewm(i) if len(txt_list) != 0: barcodeData = txt_list[0].data.decode("utf-8") for p in re.findall('projuuid=(.*)',barcodeData): if p not in projuuids and len(p) == 36: projuuids.append(p) print('%s 提取到projuuid:%s'%(h,p)) except: pass /<code>
其中,讀取二維碼的函數如下:
<code>def get_ewm(img_adds): # 讀取二維碼的內容: img_adds:二維碼地址(可以是網址也可是本地地址) if os.path.isfile(img_adds): # 從本地加載二維碼圖片 img = Image.open(img_adds) else: # 從網絡下載並加載二維碼圖片 rq_img = requests.get(img_adds).content img = Image.open(BytesIO(rq_img)) txt_list = pyzbar.decode(img) #barcodeData = txt_list[0].data.decode("utf-8") return txt_list /<code>
注意:這裡需要用到pyzbar庫,通過pip安裝即可:
<code>pip install pyzbar /<code>
- 1
3.完整代碼
<code>import re import os import requests from PIL import Image from io import BytesIO from pyzbar import pyzbar def get_ewm(img_adds): # 讀取二維碼的內容: img_adds:二維碼地址(可以是網址也可是本地地址) if os.path.isfile(img_adds): # 從本地加載二維碼圖片 img = Image.open(img_adds) else: # 從網絡下載並加載二維碼圖片 rq_img = requests.get(img_adds).content img = Image.open(BytesIO(rq_img)) txt_list = pyzbar.decode(img) #barcodeData = txt_list[0].data.decode("utf-8") return txt_list if __name__ == '__main__': # 獲取每個帖子的編號 url_tieba = 'https://tieba.baidu.com/f?kw=輕鬆籌&ie=utf-8&pn=%d' # 貼吧頁面,pn=0,50,100... p_href = 'href="/p///p2.ttnews.xyz/5fea2e730216c7e617fd375e.jpg"' hrefs = [] for i in range(1): # 爬取的頁數 try: pn = i*50 res = requests.get(url_tieba%pn) html = res.text list_herf = re.findall(p_href,html) for h in list_herf: hrefs.append('https://tieba.baidu.com/p/'+h) print('第%d頁獲取成功'%(i+1)) except: pass with open('tiezi_url.txt','w') as f: for h in hrefs: f.write(h+'\n') # 爬取每個帖子中的輕鬆籌鏈接 projuuids = [] p_projuuid = 'https://m2.qschou.com.*?projuuid=//p2.ttnews.xyz/5fea2e730216c7e617fd375e.jpg&' p_img = 'class="BDE_Image" class="lazy" data-original="//p2.ttnews.xyz/5fea2e730216c7e617fd375e.jpg"' for h in hrefs: try: res = requests.get(h) html = res.text list_projuuid = re.findall(p_projuuid,html) # 判斷帖子裡是否有直接的鏈接 if len(list_projuuid) != 0: for p in list_projuuid: if p not in projuuids and len(p) == 36: projuuids.append(p) print('%s 提取到projuuid:%s'%(h,p)) else: # 提取帖子中的圖片獲取二維碼 list_img = re.findall(p_img,html) if len(list_img) == 0: print('%s 無法提取到projuuid'%h) else: for i in list_img: txt_list = get_ewm(i) if len(txt_list) != 0: barcodeData = txt_list[0].data.decode("utf-8") for p in re.findall('projuuid=(.*)',barcodeData): if p not in projuuids and len(p) == 36: projuuids.append(p) print('%s 提取到projuuid:%s'%(h,p)) except: pass with open('projuuids.txt','w') as f: for p in projuuids: f.write(p+'\n') /<code>
三、爬取項目的數據
這裡通過遍歷之前獲得的UUID,即可獲得相應的數據:
<code>import requests import pandas as pd # 讀取projuuid with open('projuuids.txt','r') as f: projuuids = f.readlines() for i in range(len(projuuids)): # 去除尾部換行符 projuuids[i] = projuuids[i][:-1] # 獲取數據 url_api = 'https://gateway.qschou.com/v3.0.0/project/index/text3/%s' datas = [] for projuuid in projuuids: res = requests.get(url_api%projuuid) data_json = res.json() data = data_json['data']['project'] data['certification'] = data_json['data']['subsidy'][1]['subhead'].split()[-2] datas.append(data) print('%s 獲取完畢'%projuuid) datas = pd.DataFrame(datas) datas.to_csv('data.csv',encoding='utf-8',index=False) /<code>
寫在最後
至此,大功告成。我也獲得了小姐姐的讚美,嘻嘻~
最後,感謝各位大大的耐心閱讀~
慢著,大俠請留步… 動起可愛的雙手,來個贊再走唄 (๑◕ܫ←๑)