前言
本文的文字及圖片來源于網路,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理,
作者|三丨級丨狗
來源|帝都高級待業專家
緣起
周末在B站刷視頻的時候,鋼琴區一個up的視頻突然拽住了我的眼球,一連翻看了她的幾個視頻之后,我發現這個up每次的封面確實有點東西!
于是突然來了興致,想通過自己為所欲為的技術手段,實作一波兒封面批量自提,
簡單調查了一番,發現這東西用Pyhton爬蟲搞,不僅難度不大而且很有搞頭!于是很快便開始上手捋邏輯,
實施
第一次接觸爬蟲,就想要那種短平快的東西,所以我把邏輯抽離的非常宏觀:
- 想知道目標圖片的網址是什么?
- 通過代碼訪問這個網址,拿到目標頁面的全部代碼,
- 決議這個代碼,找到圖片所在區域ID
- 遍歷區域內所有的內容,找到每一個img標簽,獲取它的src屬性就是圖片的地址
- 通過代碼+地址下載對應的圖片保存到本地
- 大功告成
上面的這幾步驟基本都能看懂,有幾個步驟需要一些技術支持,分別對應是:
- 就是你訪問的地址
- urllib2或者requests
- BeautifulSoup4
- 瀏覽器的F12+選擇器找一下
- urllib
我把主邏輯理順后,寫成代碼也很簡單(這段代碼不能用哈,不用看太細):
# -*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup
#指定要爬取的網站url
x = 0
def get_images(url):
headers = {'Usar-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'}
req = urllib2.Request(url,headers=headers)# 用url地址創建一個request物件
page = urllib2.urlopen(req,timeout=20)#打開網址
contents = page.read() # 獲取原始碼
res = requests.get(url,headers=headers,timeout=(5,5))
print (res.content)
soup = BeautifulSoup(contents,'html.parser') # 創建一個soup物件
cover_imgs = soup.find_all('img')# 找到img標簽 find只找一次,find_all找到所有
for cover_img in cover_img:# 遍歷list,選取屬性
link = cover_img.get('src');#獲取src圖片路徑
link.replace(".webp",".png")
print (link);
#下載的檔案,取名字
global x
urllib. urlretrieve(link,'image\%s.png'%x)
print ("Downloading image No.{}".format(x));
x += 1;
for page in range(1,10):
url = 'https://space.bilibili.com/72956117/video?tid=0&page={}&keyword=&order=pubdate'.format(page)
get_images(url)
阻礙
這段代碼的主邏輯是通的,思路也是完全按照上面的123456來的,但是就當我已經興奮地搓搓小手準備爬圖的時候,卻遇到了很大的障礙:
「res.content拿到的并不是完整頁面的代碼」
拿到的只是一個主的html加一堆js檔案的加載路徑,并沒有拿到包含著圖片標簽的代碼,
也就是說,我通過瀏覽器訪問這個網址看到頁面的時候,其實已經進行過多次請求回應了
而我通過代碼單獨請求這個網址,只拿到了單次請求主頁的內容,所以這么搞并不能拿到指定的內容,
在這個頁面上通過右鍵查看源代碼確認了一下,確實,這個頁面的源代碼就是這個樣子滴:
那這就比較難搞了,我該如何獲知瀏覽器發出的其他請求并模擬出來,然后通過回傳拿到我想要的東西呢?
要知道一個優秀的爬蟲大佬,那都是web前后端玩兒賊6的大佬,我一個搞C++客戶端的,對這些是一竅不通啊?!一時間讓我有點一籌莫展,
不過怎么說也是個大廠的網站,讓我一沒摸過爬蟲的人上來說爬就爬了是不是有點太low了,
再想想辦法,只能硬著頭皮看請求了,
柳暗花明
這是我訪問頁面的get請求:
后面跟的請求好多,我也不是很懂,只能是憑感覺找可疑的請求查驗,
感覺上它應該是訪問后臺的某個api介面,反饋回來的是一堆json資料,然后前端根據資料給它渲染成了我們看到的樣子,
功夫不負有心人,就這么感覺了幾下還真讓我發現了一個可疑的:
看見那個api.開頭我就覺得有門,復制到瀏覽器試了一下,果然!
把這里面pic的地址扔到瀏覽器里一看!我的媽直接get到了1768*1080的原圖(在瀏覽器里F12查找元素能看到的,只有320*240的webp格式了)!比我電腦螢屏解析度都高,興奮的我大腿都拍腫了!
這個突破口有了,我們回到技術上來!
現在直接從api拿到的是json資料,所以現在思路大改!
根本不需要決議頁面,更不需要什么bs4,只需要訪問api介面,從資料里提取出圖片地址,下載圖片就完了,
不僅思路更加簡短,難度也陡然下降,
比剛才的代碼還要簡單,一共只有20行不到(這個是真的可以跑,注意身體~):
import requests
import json
import urllib
x = 0
def get_images(url):
headers = {'Usar-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'}
res = requests.get(url,headers=headers,timeout=(5,5))
for video in res.json()['data']['list']['vlist']:
global x
urllib.request.urlretrieve("http:"+video['pic'],'image\%s.jpg'%x)
print ("Downloading image No.{}".format(x));
x += 1
for page in range(1,10):
url = 'https://api.bilibili.com/x/space/arc/search?mid=72956117&ps=30&tid=0&pn={}&keyword=&order=pubdate&jsonp=jsonp'.format(page)
get_images(url)
裝上對應的庫后直接python3就可以跑,執行之前要在同級目錄創建一個名為image的檔案夾,否則沒路徑會報錯,
舉一反三
有了這個技術手段,其他up主的封面原圖,也不是問題,你需要做的只是:
- 打開這個up的個人主頁點投稿
- 按F12點到network頁面
- 重繪頁面,找到大量的webp圖片請求然后開始往上找,找到一個search?xxxx的請求
- 點擊就能看到Request url 項指定的真實api地址
- 把這個地址替換掉上面代碼里的url,執行腳本就可以下圖片了
- 爬取的頁數根據需要自己調整range,
爬取的結果,你可以沒人的時候盡情欣賞:
這個爬蟲還是很簡單的,幾乎可以說是入門都沒有的水平了,
PS:如有需要Python學習資料的小伙伴可以加下方的群去找免費管理員領取
可以免費領取原始碼、專案實戰視頻、PDF檔案等
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/10151.html
標籤:Python
