學會這招,小姐姐看你的眼神將不一樣
阿新 • • 發佈:2020-10-05
前言
今天某小麗同學來找我,有個實驗需要用到輕鬆籌的資料進行一個分析。可是沒有足夠的資料,如何辦是好?
樂於助人的我,當然不會置之不理~
(ps.畢竟是小姐姐嘛,拒絕了不好,對叭)
於是乎,我抄起傢伙,說幹就幹。
一、爬蟲分析
通過簡單的分析,可以發現輕鬆籌提供了一個介面,可以返回某個專案的相關資料,具體如下:
地址如下,xxxxxx表示專案的UUID:
https://gateway.qschou.com/v3.0.0/project/index/text3/xxxxxx
- 1
也就是說,我們只要有UUID,那麼就可以通過requests傳送請求很容易就能得到資料。這還不簡單,我們對UUID進行遍歷不就行了嘛?
然而,UUID的長度為32位,要是想遍歷的話,等明年去叭…
解決問題(小聲說:“獲得小姐姐的青睞”)
二、爬取專案ID
在官網搜尋了一番,並沒有發現哪裡有UUID。於是,我們只能另闢蹊徑。最後,我決定從百度貼吧入手,搜尋相關的帖子,並把帖子中的專案連結中的UUID提取出來。
1.抓取帖子的URL
遍歷整個“輕鬆籌吧”,抓取每個帖子的URL:
url_tieba = 'https://tieba.baidu.com/f?kw=輕鬆籌&ie=utf-8&pn=%d' # 貼吧頁面,pn=0,50,100...
p_href = 'href="/p/(.*?)"'
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')
2.提取帖子中的UUID
要獲取每個帖子裡面的專案UUID,主要有兩種方式:
(1)從帖子中的連結中提取
首先定義匹配連結的正則表示式:
p_projuuid = 'https://m2.qschou.com.*?projuuid=(.*?)&'
- 1
對帖子進行匹配:
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
(2)從帖子中的二維碼中提取
首先,我們得匹配帖子中的所有圖片,正則如下:
p_img = 'class="BDE_Image" src="(.*?)"'
- 1
然後對其中的每張圖片,進行二維碼讀取,如果包含專案連線則將其中的UUID提取出來:
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
其中,讀取二維碼的函式如下:
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
注意:這裡需要用到pyzbar庫,通過pip安裝即可:
pip install pyzbar
- 1
3.完整程式碼
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/(.*?)"'
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=(.*?)&'
p_img = 'class="BDE_Image" src="(.*?)"'
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