網友:看看胸
女:滾網友:美胸比賽
女:[圖片消息] css
繼上次知乎話題 擁有一副好身材是怎樣的體驗?
解析了知乎回答內容以後,此次咱們來解析一下微博內容,以微博網友發起的美胸大賽爲例:html
https://m.weibo.cn/detail/4367970740108457html5
https://m.weibo.cn/detail/4348022520956497python
這就是本次要獲取的微博圖片內容,共計672張很兇的照片:ajax
下面是講如何獲取的,不感興趣的話直接去公衆號回覆 套圖 便可得到。json
首先進入開發者工具看一下微博結構:工具
這只是一小部分,微博評論和微博用戶發的微博頁面,裏面都是以html5格式傳到本地的,把內容格式化以後就會發現,層級很是複雜,有興趣的能夠看一下,與其解析這個還不如用selenium更簡單一些。因而當時就產生了兩個思路:url
無論是哪種,相對於只是獲取一下圖片而言都麻煩。因而去網上搜一下,搜索結果都是前兩年爬取微博的方法,那時候仍是用 ajax 以 json 格式傳遞,如今明顯已經不是。spa
而後後面抱着僥倖心理把訪問形式改爲手機,微博域名就從 weibo.com
變成了 weibo.cn
,再看一下 network 選項卡以hotflow 開頭的 xhr :線程
這時候 weibo.cn 傳給本地信息就是簡單的 json 格式啦。上圖就是微博評論列表的評論,能夠看到每條評論若是有圖片,就會有 pic 屬性,可是要注意在 pic 下的 直接子 url 只是預覽圖連接,並不是原圖。原圖連接在pic 屬性下 large 下的 url。其餘的屬性是一些微博的標題、發送時間、內容、點贊數、評論數、轉發數和博主相關信息等。咱們此次重點是圖片,就無論其餘的了。
另外微博的反爬措施很強,真的噁心到我了,若是有大規模爬取需求,建議去淘寶買號,建 Cookie池,或者用代理池不停地切換訪問主機。若是隻用本身電腦本地Cookie,那就把請求頭弄全,並限制抓取速度。
切換到 Headers 選項卡,看一下 Request URL
:
https://m.weibo.cn/comments/hotFlowChild?cid=4376866645060411&max_id=152030087630286&max_id_type=0
能夠看出它的格式是
https://m.weibo.cn/comments/hotFlowChild?
+ cid
+ max_id
+ max_id_type
'
其中 cid 是每一條微博的惟一ID,max_id 是下一次傳回數據的最後一條評論的 ID。也就是往下翻看評論,每次顯示十條,並在此次所看的評論裏就傳回 下十條評論 的最後一條評論的惟一 ID,微博是根據這個 ID 傳回下十條內容。這也就直接限制了每次爬評論、微博、二級評論時只能一次獲取十條,也沒法利用線程池加速,由於只有獲取了這十條才知道下十條請求地址裏 max_id 的值。
而後就能夠由這些信息構造請求,獲取 json 格式的響應結果:
comment_url = 'https://m.weibo.cn/comments/hotflow?id={weibo_id}&mid={weibo_id}&max_id={max_id}&max_id_type=0' url = comment_url.format(weibo_id=id, max_id=0) response = requests.get(url, headers=headers) result = json.loads(response.text)
先獲取總評論數來計算須要多少次才能爬完評論:
total_number = result.get('data').get('total_number') total_number = int(total_number) for i in range(int(total_number / 10)): result = get_page(weibo_id) for url in parse_comment(result): save_to_img(url)
下載完圖片只有700來張才知道靠後的評論都是無用的(男士跟答主要聯繫方式什麼的)評論。
而後就是獲取圖片地址:
def parse_comment(result): if result.get('ok') and result.get('data').get('data'): comments = result.get('data').get('data') for comment in comments: if comment.get('pic'): url = comment.get('pic').get('large').get('url') yield url
要先 if comment.get('pic')
一下,這很重要,由於不少無用評論並無配圖,也就是沒有 pic 屬性,要以這種方式過濾掉。
另外還有這個:
這裏的二級評論就頗有必要爬一下,看一下結構:
值得注意的是二級評論裏無論有沒有圖片都不會有 pic 屬性,圖片在回答內容text 裏以 css 方式嵌套的,很明顯就是 a 標籤下的 href 屬性 就是圖片地址。用 pyquery 取出來地址:
childs_comment = result.get('data') for child_comment in childs_comment: text = child_comment.get('text') content = pyquery.PyQuery(text) url = content('a').attr('href') yield url
存儲圖片以圖片內容的 md5 值命名,能夠去重:
response = requests.get(url) if response.status_code == 200:img_path = '{0}/{1}.{2}'.format(path,md5(response.content).hexdigest(), 'jpg') # 以圖片的md5字符串命名防止重複圖片
最後接入某大廠的人體特徵值檢測,考慮到圖片大多沒有露臉,識別男女性別不夠準,這裏只把未識別出人體的圖片去掉了(一些表情圖)。
有興趣的能夠公衆號回覆 套圖 得到此次微博圖片和上次知乎圖片本次微博結構比較簡單,與上次關於知乎的文章差很少,再也不提供源碼。
公衆號:愛寫bug(ID:iCodeBugs)