50?python爬?代碼, 帶你正確打開知乎新世界!

作者:聶大哥的CS小弟 @Hunting

本篇適用於,

想學爬蟲,

也有一丟丟Python基礎的,

小白2.0們。

老司機開車,

上車請坐穩!

---------- 小弟yy的對話場景 ----------

?哥:快看快看,這個?姐姐腿好長好?!

小弟:唉,知乎現在是世風?下,好好的問答社區,你說你們這些?怎麼就喜歡看低俗的?H圖?你還是個已婚人妻!!!

?哥: 哇,?機內存不夠了,?電腦保存?姐姐們的照?吧。

小弟:我說,你們看就看吧,還要?個個右鍵點開圖?保存?清?圖。。。

?哥:好?煩啊,?百張圖?我?都擼酸了,嘿嘿嘿。。。

小弟:什麼?還想要偷懶?問我有沒有簡單的辦法,可以?次性下載完所有圖??

?哥:雙眼布靈布靈(可憐狀)。。。

小弟:好吧,其實呢,我是不屑於看這些低俗的?H圖的。但既然你們這麼求我,我就勉為其難地寫個爬?代碼,滿??下你們饑渴的?靈。。。

Section 1 - 準備工作

0. 你以為第一件事情就是要學習知識,搭建環境么?當然不是,第?件事情當然是確??標,睜?雙眼,發現這個世界的美,嘿嘿嘿。。。我呢,給你們先列?個知乎問題鏈接,先點進去看看,你們肯定會回來努?學習的(圍笑)。

你的?常搭配是什麼樣??

?材好是?種怎樣的體驗?

拍照時怎樣擺姿勢好看?

?性胸部過?會有哪些困擾與不便?

腿長是?種什麼體驗?

??腿好看胸平是?種什麼體驗?

短髮?孩要怎麼拍照才性感?

1. ?先,你要在電腦?安裝 python 的環境,我會提供2.7和3.6兩個版本的代碼,

但是本?只以python3.6版本為例。

我建議不管是Win還是Mac?戶,都最好下載?個 anaconda,?於管理python庫和環境。

  • (Anaconda下載鏈接)continuum.io/downloads
  • (用戶手冊)conda.io/docs/test-driv

安裝完成後,打開你電腦的終端(Terminal)執?以下命令:

# 搭建 python 3.6環境,爬蟲專用。如果你已經裝好了 python3.6的環境,那麼可以跳過搭建環境這一步,直接安裝所需要的 python庫。nconda create --name crawler python=3.6nn# 檢查環境是否已創建nconda info --envsnn# 激活python3.6環境n# Mac/Linux 用戶nsource activate crawler #激活nsource deactivate #退出nn# Win 用戶nactivate crawler # 激活ndeactivate # 退出nn# 檢查 python 版本npython --versionn

2. 因為知乎?站前端是? react 搭建的,頁?內容隨著?戶?標滾軸滑動、點擊

依次展現,為了獲取海量的圖?內容,我們需要?selenium這個 lib 模擬?戶對瀏覽

器進?滑動點擊等操作。

  • pypi.python.org/pypi/se

# 利? pip 安裝 seleniumnpip install -U seleniumn

下載安裝完成後,我建議?家打開上?的鏈接,閱讀?下 selenium 的使??法。意思?致為,為了運? selenium,我們需要安裝?個 chrome 的 driver,下載完成後,對於 Mac ?戶,直接把它複製到/usr/bin或者/usr/local/bin,當然你也可以?定義並添加路徑。對於 Win ?戶,也是同理。

  • Chrome: sites.google.com/a/chro
  • Firefox: github.com/mozilla/geck
  • Safari: webkit.org/blog/6900/we

3. 在爬?的時候我們經常會發現?頁都是經過壓縮去掉縮進和空格的,頁?結構會很不清晰,這時候我們就需要? BeautifulSoup 這個 lib 來進?html ?件結構化。

pip install beautifulsoup4n

Section 2 - 代碼解釋

2.0 Import Libraries

from selenium import webdrivernimport timennimport urllib.requestnnfrom bs4 import BeautifulSoupnnimport html.parsern

2.1 確定目標URL

在 main 函數裡邊,打開chrome driver,然後輸入 url

def main():n # ********* Open chrome driver and type the website that you want to view ***********************nn driver = webdriver.Chrome() # 打開瀏覽器nn # 列出來你想要下載圖片的網站nn # driver.get("https://www.zhihu.com/question/35931586") # 你的日常搭配是什麼樣子?n # driver.get("https://www.zhihu.com/question/61235373") # 女生腿好看胸平是一種什麼體驗?n # driver.get("https://www.zhihu.com/question/28481779") # 腿長是一種什麼體驗?n # driver.get("https://www.zhihu.com/question/19671417") # 拍照時怎樣擺姿勢好看?n # driver.get("https://www.zhihu.com/question/20196263") # 女性胸部過大會有哪些困擾與不便?n # driver.get("https://www.zhihu.com/question/46458423") # 短髮女孩要怎麼拍照才性感?n driver.get("https://www.zhihu.com/question/26037846") # 身材好是一種怎樣的體驗?n

2.2 模擬滾動點擊操作

在 main 函數?我們定義?個重複執?的函數,來進?滾動和點擊的操作。?先我們可以?driver.execute_scrip來進?滾動操作。通過觀察,我們發現知乎問題底部有?個「查看更多回答的」的按鈕,如下圖。因此我們可以?driver.find_element_by_css_selector來選中這個按鈕,並點擊。為了愛護?朋友們的?體,我們這?只爬取五個頁?的圖?。其實,五個頁?,100個回答,往往都能有1000張圖?了。。。

# ****************** Scroll to the bottom, and click the "view more" button *********n def execute_times(times):nn for i in range(times):n driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 滑動到瀏覽器底部n time.sleep(2) # 等待頁面載入n try:n driver.find_element_by_css_selector(button.QuestionMainAction).click() # 選中並點擊頁面底部的載入更多n print("page" + str(i)) # 輸出頁面頁數n time.sleep(1) # 等待頁面載入n except:n breaknn execute_times(5) # 注意身體,五個頁面夠了的(微笑)n

2.3 結構化HTML頁面並保存

我們每次爬取頁?信息,要做的第?件事就是把頁? HTML 存儲下來。為了?便我們?眼瀏覽,這時候就需要?beautifulSoup把壓縮後的 HTML ?件結構化並保存。

# **************** Prettify the html file and store raw data file *****************************************nnresult_raw = driver.page_source # 這是原網頁 HTML 信息nresult_soup = BeautifulSoup(result_raw, html.parser)nnresult_bf = result_soup.prettify() # 結構化原 HTML 文件nnwith open("./output/rawfile/raw_result.txt", w) as girls: # 存儲路徑里的文件夾需要事先創建。n girls.write(result_bf)ngirls.close()nprint("Store raw data successfully!!!")n

2.4 爬取知乎問題回答里的<img> nodes

要知道,在我們每次想要爬取頁?信息之前,要做的第?件事就是觀察,觀察這個頁?的結構,量??裁。?般每個頁??都有很多個圖?,?如在這個知乎頁??,有很多?戶頭像以及插?的圖?。但是我們這?不想要?戶頭像,我們只想要要回答問題?的照?,所以不能夠直接爬取所有 <img> 的照?。通過觀察,我發現每?個圖?附近都會有?個<noscript>的node,?邊不僅有縮略圖 URL 還有?清原圖的 URL。因此,我為了偷懶,就直接把所有<noscript>給爬了下來。仔細觀察,你會發現每個<noscript>的<>都是被 escape(HTML entity 轉碼)了的,所以要?html.parser.unescape進?解碼。

# **************** Find all <nonscript> nodes and store them *****************************************nwith open("./output/rawfile/noscript_meta.txt", w) as noscript_meta: # 存儲路徑里的文件夾需要事先創建。n noscript_nodes = result_soup.find_all(noscript) # 找到所有<noscript>noden noscript_inner_all = ""n for noscript in noscript_nodes:n noscript_inner = noscript.get_text() # 獲取<noscript>node內部內容n noscript_inner_all += noscript_inner + "n"nn noscript_all = html.parser.unescape(noscript_inner_all) # 將內部內容轉碼並存儲n noscript_meta.write(noscript_all)nnnoscript_meta.close()nprint("Store noscript meta data successfully!!!")n

轉碼後,結果如下(琳琅滿目的高清無碼大圖 URL):

2.5 下載圖片

有了 img 的所有 node,下載圖?就輕鬆多了。??個 urllib.request.urlretrieve就全部搞定。這?我又做了?點清理,把所有的 url 單獨存了?下,並?序號標記,你也可以不要這?步直接下載。

# **************** Store meta data of imgs *****************************************n img_soup = BeautifulSoup(noscript_all, html.parser)n img_nodes = img_soup.find_all(img)n with open("./output/rawfile/img_meta.txt", w) as img_meta:n count = 0n for img in img_nodes:n if img.get(src) is not None:n img_url = img.get(src)nn line = str(count) + "t" + img_url + "n"n img_meta.write(line)n urllib.request.urlretrieve(img_url, "./output/image/" + str(count) + ".jpg") # 一個一個下載圖片n count += 1nn img_meta.close()n print("Store meta data and images successfully!!!")n

記得還有最後的!!!

if __name__ == __main__:n main()n

2.6 您好,您的小H圖大禮包已送達!

成功後,你會看到以下消息。然後你就可以孤身一人躲在被窩裡嘿嘿嘿了。。。

# ***大哥:小弟變成這樣真的不是我教的?????? ***

因為考慮到肖像問題,只展示圖庫的冰山一小角(不露臉的),隨便給吃瓜群眾們展示一下:

圖侵刪!!!

習慣性衣來伸手飯來張口的客官們!

代碼已經給爺準備好了:

github.com/huntingzhu/w

Python 2.7和Python 3.6的代碼都有......

原發於公眾號:「大數據應用(Datalaus)」

知乎ID:數據應用學院

推薦閱讀:

TAG:Python | 数据分析 | 爬虫 |