從零開始寫Python爬蟲 --- 1.8 爬蟲實踐: 電影排行榜和圖片批量下載
這次我們要寫的是爬取熱門電影排行榜,依舊十分的簡單,目的在於再次鞏固已經學到的知識。由於用的還是前面幾章用到的老套路,文章里我就不過多的贅述了。
目標分析:
這次要爬的網站是:
http://dianying.2345.com/top/
網站結構分析:
先來簡單看一下網站的結構:
可以看到,我們需要的主題部分,都被包裹在『<ul>「列表標籤里,
那麼我們簡單的用bs4庫找到 "<ul>" tag并迭代取出每一條「<li>」tag,
最後再從沒個<li>標籤里找到我們需要的信息就行。
遇到的問題?
這次的代碼十分的簡單,但是我在實現的過程中遇到了一些小問題:
編碼編碼編碼,還是編碼:
我一開始在抓取網頁文本的時候,依舊的採用的是:
r.encoding=r.apparent_encoding
本來以為會萬無一失,沒想到抓取下來的文本居有部分亂碼。
比如這個叫 辰頡詮 的演員
爬取下來居然是:於是我稍微調試了一下:
print (r.encoding)# gbkprint (r.apparent_encdoing)# GB2312
原來問題出在這這裡,requests庫從GET下來的body中分析了一下編碼,
得出的結論是 :GB2312 。
而這個編碼實際上和網站的編碼是不同的,
所以才會得到個別的亂碼。
解決方式也很簡答,手動將編碼設置成GBK就解決了。
那麼GBK 和 GB2312之間到底有什麼區別呢?
以下內容來自wiki百科:GBK:漢字內碼擴展規範,稱GBK,全名為《漢字內碼擴展規範(GBK)》1.0版,由中華人民共和國全國信息技術標準化技術委員會1995年12月1日制訂,國家技術監督局標準化司和電子工業部科技與質量監督司1995年12月15日聯合以《技術標函[1995]229號》文件的形式公布。 GBK共收錄21886個漢字和圖形符號,其中漢字(包括部首和構件)21003個,圖形符號883個。
GBK的K為漢語拼音Kuo Zhan(擴展)中「擴」字的聲母。英文全稱Chinese Internal Code Extension Specification。
GB2312
GB 2312 或 GB 2312–80 是中華人民共和國國家標準簡體中文字符集,全稱《信息交換用漢字編碼字符集·基本集》,又稱GB0,由中國國家標準總局發布,1981年5月1日實施。GB 2312編碼通行於中國大陸;新加坡等地也採用此編碼。中國大陸幾乎所有的中文系統和國際化的軟體都支持GB 2312
既然都說到這裡了,也來介紹一下UTF-8
UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字元編碼,也是一種前綴碼。它可以用來表示Unicode標準中的任何字元,且其編碼中的第一個位元組仍與ASCII兼容,這使得原來處理ASCII字元的軟體無須或只須做少部分修改,即可繼續使用。因此,它逐漸成為電子郵件、網頁及其他存儲或發送文字的應用中,優先採用的編碼。
我們可以得知,GBK和GB2312 都是中文體系下的編碼方式,按
道理來說,不會出現問題,那為什麼那位演員的名字沒有顯示出來呢?
其實很簡單啊,GBK比GB2312後推行,自然也就支持更多漢字的顯示,
例如那位演員名字中的生僻字 「頡詮」
當然,我的個人偏好依舊是是UTF-8 他對中文有著及其強大的支持,怎麼說呢,希望Unicode能早點統一整個web編碼吧!
還有各家系統的換行符 也是一個坑。總之就是異常的難受,這當中當然有很多歷史和商業原因,Mac : 「
Win : "
」"
Linxu: "
"或者"
"
想了解的小夥伴可以自己去查查看~
圖片下載:
在電影排行榜爬蟲當中,我們有一項目標是:『爬取每個電影的標題圖』,
有人肯定就覺得很難實現,因為圖片又不是字元,如何以文本的形式爬下來呢?
其實,這裡有一個誤區,在計算機的世界裡,一切的數據歸根到底都是以「0」和「1」的二進位形式存在的。
圖片自然也不例外,任何一張圖片,都是以「位元組流 」的形式,
通過了一定的編碼方式,被計算機排列組合,從而顯示成我們肉眼所看到的圖片。
那麼我們只要把圖片數據從網上下載下來,然後再以二進位的格式寫入到本地就可以啦。
給出一個圖片下載的通用代碼片段:
import requests def get_pic_from_url(url): #從url以二進位的格式下載圖片數據 pic_content = requests.get(url,stream=True).content open("filename","wb").write(pic_content)
是不是很簡答呢? 當然,你們也可以在這個基礎上進行添加和完善。
代碼的書寫:
由於這次的代碼比較簡單。並且也沒有太多的新的東西,我就不一一解釋了,直接貼上代碼。另外,代碼里有詳細的注釋:
"""爬取最新電影排行榜單url:http://dianying.2345.com/top/使用 requests --- bs4 線路Python版本: 3.6OS: mac os 12.12.4"""import requestsimport bs4def get_html(url): try: r = requests.get(url, timeout=30) r.raise_for_status # 該網站採用gbk編碼! r.encoding = "gbk" return r.text except: return "someting wrong"def get_content(url): html = get_html(url) soup = bs4.BeautifulSoup(html, "lxml") # 找到電影排行榜的ul列表 movies_list = soup.find("ul", class_="picList clearfix") movies = movies_list.find_all("li") for top in movies: #找到圖片連接, img_url=top.find("img")["src"] name = top.find("span",class_="sTit").a.text #這裡做一個異常捕獲,防止沒有上映時間的出現 try: time = top.find("span",class_="sIntro").text except: time = "暫無上映時間" #這裡用bs4庫迭代找出「pACtor」的所有子孫節點,即每一位演員解決了名字分割的問題 actors = top.find("p",class_="pActor") actor= "" for act in actors.contents: actor = actor + act.string +" " #找到影片簡介 intro = top.find("p",class_="pTxt pIntroShow").text print("片名:{} {}
{}
{}
".format(name,time,actor,intro) ) #我們來吧圖片下載下來: with open("/Users/ehco/Desktop/img/"+name+".png","wb+") as f: f.write(requests.get(img_url).content)def main(): url = "http://dianying.2345.com/top/" get_content(url)if __name__ == "__main__": main()
結果展示:
電影信息輸出:
圖片下載:
好了,本次的小例子到這裡就結束了,其實學到這裡,bs4庫的基本用法我們也掌握了,爬蟲的基本思路相信大家心裡也都有個數,那麼我們接下來是不是要學更加高級的技術了呢?別急,慢慢來,先自己動手多寫幾個小demo。相信你會有更大的收穫!
最近學校里在本科教學評估,也不能翹課在家寫代碼,到了學期末一堆論文等著我,再次感嘆一下文科生傷不起!調個論文格式我都要上天了!??
每天的學習記錄都會 同步更新到:
微信公眾號: findyourownway知乎專欄:從零開始寫Python爬蟲 - 知乎專欄blog : www.ehcoblog.mlGithub: Ehco1996/Python-crawler
推薦閱讀:
※基於TCP的python聊天程序
※學會最簡單的資料庫|看完這7招就夠了
※Python 高級編程:理解生成器
※Python Generator漫談
※在 Pycom 使用 Python + Micropython + MQTT 進行物聯網編程