Python爬蟲入門實戰之貓眼電影數據抓取!

前言

本文可能篇幅較長,但是絕對乾貨滿滿,提供了大量的學習資源和途徑。達到讓讀者獨立自主的編寫基礎網絡爬蟲的目標,這也是本文的主旨,輸出有價值能夠真正幫助到讀者的知識,即授人以魚不如授人以漁,讓我們直接立刻開始吧,本文包含以下內容:

  • Python環境搭建與基礎知識
  • 爬蟲原理概述
  • 爬蟲技術概覽
  • 貓眼電影排行數據抓取
  • Ajax數據爬取貓眼電影票房
  • 更多進階,代理、模擬登陸、APP 爬取等…..

Python環境搭建與基礎知識

Python環境搭建

Anaconda安裝

此處筆者並不會介紹Python軟件的安裝,有讀者可能會疑問Python都不安裝,我怎麼學習先進的Python知識呢? 不要著急,此處筆者介紹了一種新的Python快速安裝方式,即直接安裝Anaconda,Anaconda是什麼呢? Anaconda 是一個Python的發行版,包括了Python和很多常見的Python庫, 和一個包管理器cond,Anaconda是專注於數據分析的Python發行版本,包含了conda、Python等720多個科學包及其依賴項,適用於企業級大數據分析的Python工具。在數據可視化、機器學習、深度學習等多方面都有涉及。不僅可以做數據分析,甚至可以用在大數據和人工智能領域。有讀者可能會疑問這和爬蟲有什麼關係呢,當然有關係,在編寫爬蟲程序的過程中需要使用Python庫,而Anaconda就已經包含這些經常使用庫,這對安裝Python庫感到頭疼的讀者再好不過了。當然這一切都是免費的,接下來我們就開始安裝美妙的Anaconda吧。 首先從Anaconda官網下載對應版本的Anaconda,如果下載速度過慢推薦使用國內的清華大學開源軟件鏡像站選擇對應的Anaconda下載,Anaconda的官網下載頁面如下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!

本文推薦下載Python3.6對應的版本,以筆者為例電腦環境為:Windows-64Bit,下載的對應版本為:Anaconda3-5.2.0-Windows-x86_64,下載完成後打開安裝包如下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!

點擊 next

Python爬蟲入門實戰之貓眼電影數據抓取!

點擊 I Agree

Python爬蟲入門實戰之貓眼電影數據抓取!

選擇 Just Me ,點擊 next

Python爬蟲入門實戰之貓眼電影數據抓取!

選擇安裝目錄,點擊next

Python爬蟲入門實戰之貓眼電影數據抓取!

Python學習群:683380553,有大牛答疑,有資源共享!是一個非常不錯的交流基地!歡迎喜歡Python的小夥伴!

勾選 Add Anaconda to my PATH environment variable ,然後點擊 install 安裝即可

IDE環境搭建

IDE筆者推薦使用Pycharm,其中免費的社區版已經能夠滿足我們的需求,使用教程可以參考CSDN博客Pycharm簡單使用教程,或者直接在CSDN搜索pycharm教程獲取更多知識。此處可以詳細介紹下

1.1Python 基礎技術

我不會介紹過於基礎內容,因為這些內容互聯網上已經大量免費的基礎入門教程了,但是筆者會給大家提供一些互聯網的免費學習資源和方法,讓大家快速學會編寫爬蟲程序所需要的Python基礎知識和進階知識,而對於基礎的爬蟲我們需要掌握的Python知識有以下:

  • 數據類型
  • 列表
  • 循環語句
  • 判斷語句
  • 函數

Python基礎

對於完全沒有Python基礎的讀者,可以學習下面的快速入門

  • Python3 教程 | 菜鳥教程
  • Python教程 | 廖雪峰的官方網站
  • Python 教程| 簡明教程
  • Python教程™
  • 笨辦法學Python | 看雲
  • The Python Tutorial | Python 3.6.6 documentation

Python官方文檔,具有絕對的權威和全面,但是文檔本身是英文,所以對大部分初學者來說並不是很友好,下面是國人翻譯的Python版本,對英文感冒的讀者可以選擇該版本學習:

  • Python 入門指南 | python tutorial 3.6.3 documentation 一些入門的書籍推薦
  • 《Python編程 從入門到實踐》
  • 《Python基礎教程(第3版)》 Python進階 對於想要提升自己技術的讀者,接下的書籍和資料應該是很符合你的胃口了 :
  • The Python Standard Library
  • 《Python CookBook 3》
  • 《流暢的Python》
  • 《Python學習手冊(第4版)》
  • 《Python核心編程(第3版)》
  • 《數據結構 Python語言描述》
  • 《Python高性能編程》

爬蟲是什麼

爬蟲原理

爬蟲是什麼?爬蟲從本質上說就是在模擬HTTP請求,記住這句話,這就是我們後面經常需要做的事情。一般用戶獲取網絡數據的方式有兩種: a. 瀏覽器提交HTTP請求--->下載網頁代碼--->解析成頁面。 b. 模擬瀏覽器發送請求(獲取網頁代碼)->提取有用的數據->存放於數據庫或文件中。 爬蟲就是在做第二種事情,大致過程如下: i. 通過HTTP庫向目標站點發起請求,即發送一個Request,請求可以包含額外的headers等信息,等待服務器的響應 ii. 如果服務器正常響應,會得到一個Response,Response的內容便是所要獲取的頁面內容,類型可能有HTML、JSON、二進制文件(如圖片、視頻等類型)。 iii. 得到的內容可能是HTML,可以用正則表達式、網頁解析庫進行解析。可能是JSON,可以直接轉成JOSN對象進行解析,可能是二進制數據,可以保存或者進一步處理 iv. 保存形式多樣,可以保存成文本,也可以保存至數據庫,或者保存成特定格式的文件。 許多讀者可能不知道上面具體在做什麼,那麼接下來我們通過瀏覽器抓包分析上面的過程,筆者推薦使用Chrome,對開發者很友好,後續我們會經常使用到,Chrome下載,如果下載速度較慢,建議使用國內Chrome鏡像下載安裝。 首先打開瀏覽器在地址欄輸入 https://www.baidu.com/ (讀者也可以使用其他網頁測試比如咱們的https://gitbook.cn/),回車,百度頁面映面而來,然後按下F12,瀏覽器開發者選項的快捷鍵,選擇Network欄目,打開界面下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!

按下F5刷新頁面:

Python爬蟲入門實戰之貓眼電影數據抓取!

欄目裡面更新了大量的數據包,這些包就是瀏覽器請求的數據,我們想要的數據就在這些請求裡面

  • 第一列Name:請求的名稱,一般會將URL的最後一 部分內容當作名稱。
  • 第二列Status: 響應的狀態碼,這裡顯示為200,代表響應是正常的。通過狀態碼,我們可 以判斷髮送了請求之後是否得到了正常的響應。
  • 第三列Type: 請求的文檔類型。這裡為document, 代表我們這次請求的是一個HTML文檔,內容就是一些HTML代碼。
  • 第四列initiator: 請求源。用來標記請求是由哪個對象或進程發起的。
  • 第五列Size: 從服務器下載的文件和請求的資源大小。如果是從緩存中取得的資源,則該列會顯示from cache。
  • 第六列Time:發起請求到獲取響應所用的總時間。
  • 第七列Waterfall:網絡請求的可視化瀑布流。 接下來我們分析請求的詳細組成,比如點第一個請求即Name為www.baidu.com的請求,如下圖所示:
Python爬蟲入門實戰之貓眼電影數據抓取!

我們看到響應中分General部分,請求頭、響應頭

General一般包含以下部分:

  • Request URL為請求的URL
  • Request Method為請求的方法
  • Status Code為響應狀態碼,
  • Remote Address為遠程服務器的地址和端口

Response Headers一般包含以下部分(響應(服務端->客戶端[response])):

  • HTTP/1.1為響應採用的協議和版本號 200 (狀態碼) OK(描述信息)
  • Location為服務端需要客戶端訪問的頁面路徑
  • Server為服務端的Web服務端名
  • Content-Encoding為服務端能夠發送壓縮編碼類型
  • Content-Length為服務端發送的壓縮數據的長度
  • Content-Language為服務端發送的語言類型
  • Content-Type為服務端發送的類型及採用的編碼方式
  • Last-Modified為服務端對該資源最後修改的時間
  • Refresh為服務端要求客戶端1秒鐘後,刷新,然後訪問指定的頁面路徑
  • Content-Disposition為服務端要求客戶端以下載文件的方式打開該文件
  • Transfer-Encoding為分塊傳遞數據到客戶端
  • Set-Cookie為服務端發送到客戶端的暫存數據
  • Connection為維護客戶端和服務端的連接關係

Request Headers 一般包含以下部分(請求(客戶端->服務端[request])):

  • GET(請求的方式) /newcoder/hello.html(請求的目標資源) HTTP/1.1(請求採用的協議和版本號)
  • Accept為客戶端能接收的資源類型
  • Accept-Language為客戶端接收的語言類型
  • Connection為維護客戶端和服務端的連接關係
  • Host: localhost為連接的目標主機和端口號
  • Referer告訴服務器我來自於哪裡
  • User-Agent為客戶端版本號的名字
  • Accept-Encoding為客戶端能接收的壓縮數據的類型
  • If-Modified-Since為緩存時間
  • Cookie為客戶端暫存服務端的信息
  • Date為客戶端請求服務端的時間 而我們需要做的就是模擬瀏覽器提交Requests Headers獲取服務器的響應信息,從而得到我們想要的數據,想要深入瞭解的讀者請訪問HTTP | MDN文檔瞭解更多信息。

爬蟲能抓什麼樣的數據

在網頁中我們能看到各種各樣的信息,最常見的就是用戶能夠看到的網頁頁面,而通過瀏覽器的開發者工具對網頁請求進行抓包時我們可以看見大量的請求,即有些網頁返回的不是HTML代碼,可能是json字符串,各種二級制數據,比如圖片、音頻、視頻等,當然還有些是CSS、JavaScript等文件。那麼即瀏覽器能夠獲取的數據,爬蟲程序都能獲取到,而瀏覽器的數據是翻譯給用戶看到的信息,即只要能夠在瀏覽器訪問到的信息,爬蟲程序就都能夠抓取下來。

爬蟲技術概覽

^_^:本節介紹爬蟲經常使用到的技術,比如請求:requests,信息提取:Xpath,Re正則,json,存儲:CSV,MySQL, MongoDB,模擬瀏覽器Selenium,保證在項目實戰中涉及的技術讀者都會,也就是這裡需要講清楚這些技術的使用方法,

第一個請求

Requests庫

Requests庫,官方文檔是這樣描述:Requests 唯一的一個非轉基因的 Python HTTP 庫,人類可以安全享用。警告:非專業使用其他 HTTP 庫會導致危險的副作用,包括:安全缺陷症、冗餘代碼症、重新發明輪子症、啃文檔症、抑鬱、頭疼、甚至死亡。 Requests 是以PEP 20 (即著名的Python之禪)的箴言為中心開發的,下面就是Requests的開發哲學,望讀者能夠細細品讀,寫出更加Pythonic的代碼。

Beautiful is better than ugly.(美麗優於醜陋) Explicit is better than implicit.(直白優於含蓄) Simple is better than complex.(簡單優於複雜) Complex is better than complicated.(複雜優於繁瑣) Readability counts.(可讀性很重要)

在2.1中我們談到爬蟲的原理就是進行HTTP請求然後得到響應,在響應中提取我們想要的信息並保存。而Requests庫就是利用Python模擬HTTP請求的利器。如果讀者已經安裝了Anaconda,那麼Requests庫就已經可用了,如果沒有Requests庫,讀者可以在命令行中(win+R 輸入 cmd)pip install requests 安裝requests庫,接下來就開始我們的第一個請求吧! 使用Requests發送HTTP請求非常簡單,接下來我們就以GitChat為例:

# 導入requests 模塊
import requests
# 發起Get請求並返回Response對象,包含服務器對HTTP請求的響應
response = requests.get('https://gitbook.cn/')
# 打印 響應狀態碼
print(response.status_code)
# 打印 str類型的響應體,比如一個普通的 HTML 頁面,需要對文本進一步分析時,使用 text
print(response.text)
複製代碼

部分運行的結果如下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!

Requests不僅支持Get方式請求,比如Post請求:

# 導入 requests 模塊
import requests
# 需要提交的表單數據
data = {
'name': 'ruo', 'age': 22
}
# 發起Post請求
response = requests.post("http://httpbin.org/post", data=data)
# 響應體內容
print(response.text)
複製代碼

部分運行的結果如下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!

當然Requests還支持更多的請求方式,比如以下請求,筆者就不一一演示了,最常用的請求就是以上Get和Post兩種請求方式。

# PUT請求
requests.put(“http://httpbin.org/put”)
# DELETE請求
requests.delete(“http://httpbin.org/delete”)
# HEAD請求
requests.head(“http://httpbin.org/get”)
# OPTIONS請求
requests.options(“http://httpbin.org/get”)
複製代碼

由於大多數服務器都會通過請求頭中的User-Agent識別客戶端使用的操作系統及版本、瀏覽器及版本等信息,所以爬蟲程序也需要加上此信息,以此偽裝瀏覽器;如果不加上很可能別識別出為爬蟲,比如當我們不加Headers對知乎進行get請求時:

# 導入 requests 模塊
import requests
# 發起Get請求
response = requests.get("https://www.zhihu.com")
# 狀態碼
print(response.status_code)
# 響應體內容
print(r.text)
複製代碼

返回的內容如下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!

我們可以看見返回的400的狀態碼,及請求無效,接著我們在請求裡添加Headers,然後添加User-Agent信息,再次嘗試請求:

# 導入 requests 模塊
import requests
# 在Headers中添加User-Agent字段信息
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
# 發起Get請求
response = requests.get("https://www.zhihu.com", headers=headers)
# 狀態碼
print(response.status_code)
# 響應體內容
print(response.text)

複製代碼

返回的內容如下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!

可以看見請求成功,並返回了正確的響應狀態碼和響應體。 想要更深入的學習Requests的讀者可以訪問Requests官方原文文檔或者 中文文檔 。

提取信息

當我們通過HTTP請求獲取到響應後,加下來就需要提取響應體中的內容,此處筆者介紹兩種常用的提取方法,一個是正則表達式,另一個是Xpath。

正則表達式

正則表達式是一個很強大的字符串處理工具,幾乎任何關於字符串的操作都可以使用正則表達式來完成,作為一個爬蟲工作者,每天和字符串打交道,正則表達式更是不可或缺的技能。有了它,從HTML裡提取想要的信息就非常方便了。 讀者可以通過 正則表達式 | 廖雪峰的官方網站 快速入門,也可以通過 Python正則表達式 | 菜鳥教程 學習Python中操作正則和使用正則,Python的官方文檔中Python標準庫的6.2節也對Re有詳細的介紹和使用教程。 初次接觸正則表達式的讀者可能會覺得有些抽象,有點難入門,因為畢竟正則表達式本身就是一種小型的、高度專業化的編程語言,以上的入門教程瞭解後,這裡給讀者介紹一個提取信息通用的正則字符串 .*?,該規則能夠以非貪婪的方式匹配任意字符,後面我們會經常使用到。 比如我們需要匹配

Chapter 1 - 介紹正則表達式

標籤中的內容,我們可以:
# 導入 re 模塊
import re
# 待匹配文本
h1 = '

Chapter 3.2.1 - 介紹正則表達式

'
# 將正則字符串編譯成正則表達式對象,方便在後面的匹配中複用

pat = re.compile('

(.*?)

', re.S)
# re.search 掃描整個字符串並返回第一個成功的匹配
result = re.search(pat, h1)
# 匹配的整個表達式的字符串,group() 可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應值的元組。
print(result.group(0))
# 匹配的第一個括號內的字符串,group() 可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應值的元組。
print(result.group(1))
複製代碼

以下是匹配結果:

Python爬蟲入門實戰之貓眼電影數據抓取!

Xpath

XPath即為XML路徑語言(XML Path Language),它是一種用來確定XML文檔中某部分位置的語言。 XPath基於XML的樹狀結構,提供在數據結構樹中找尋節點的能力。起初XPath的提出的初衷是將其作為一個通用的、介於XPointer與XSL間的語法模型。但是XPath很快的被開發者採用來當作小型查詢語言,在爬蟲中提取信息也是不錯的好幫手。 讀者可以通過 Xpath 教程 | 菜鳥教程 學習Xpath的原理及編寫方法,也可以訪問CSDN博客中搜索Python Xpath學習更多Python中Xpath的基本操作,接下來介紹編寫“編寫”的技巧和在Python中使用的方法,之所以加上“編寫”,讀者看下面便知。 還記得在2.1爬蟲原理中使用的瀏覽器的開發者工具嗎,我們可以通過這個工具直接獲取對應節點的Xpath規則,從而達到快速利用Xpath提取網頁信息的目的,例如提取貓眼電影TOP100榜中的電影信息,首先打開瀏覽器輸入http://maoyan.com/board/4,將鼠標移動到需要提取的信息(電影名稱)上,右鍵選擇檢查,如下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!

接著我們選擇下面的元素,右鍵選擇Copy-->xpath, 如下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!

獲取了該節點的xpath規則了,接下來我們編寫Python程序驗證該規則是否能夠真正提取電影名:

import requests
# 導入lxml庫的etree模塊
from lxml import etree
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
url = 'http://maoyan.com/board/4'

response = requests.get(url, headers=headers)
html = response.text
# 調用HTML類進行初始化
html = etree.HTML(html)
# 粘貼我們copy的xpath,提取電影名 “霸王別姬”
result_bawangbieji = html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd[1]/div/div/div[1]/p[1]/a')
# 打印節點標籤包含的文本內容
print(result_bawangbieji[0].text)
# 提取該頁面所有電影名,即選擇所有'dd'標籤的電影名
result_all = html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd/div/div/div[1]/p[1]/a')
# 打印所有提取出的電影名
print('該頁面全部電影名:')
for one in result_all:
print(one.text)
複製代碼

結果如下圖所示,我們成功提取了HTML中電影名的信息:

Python爬蟲入門實戰之貓眼電影數據抓取!

存儲信息

TEXT 文本存儲

如果讀者學習了Python的基礎知識,那麼應該比較熟悉這種基本信息存儲方式,即直接將我們需要存儲的信息寫入文件中,比如常見的TEXT文件,如果不熟悉的讀者可以通過 Python文件讀寫 - Python教程™ 快速概覽,下面我們就對3.2.2中Xpath提取的電影名進行文件存儲操作:

import requests
from lxml import etree
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
url = 'http://maoyan.com/board/4'
response = requests.get(url, headers=headers)
html = response.text
# 調用HTML類進行初始化
html = etree.HTML(html)
# 粘貼我們copy的xpath,提取電影名 “霸王別姬”
result_bawangbieji = html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd[1]/div/div/div[1]/p[1]/a')
# 打印節點標籤包含的文本內容
print(result_bawangbieji[0].text)
# 提取該頁面所有電影名
result_all = html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd/div/div/div[1]/p[1]/a')
# 打印所有提取出的電影名
print('該頁面全部電影名:')
for one in result_all:
print(one.text)
# 將這一頁電影名存儲至TEXT文件中,'a' 指打開一個文件進行追加。 如果文件存在,則文件指針位於文件末尾。也就是說,文件處於追加模式。如果文件不存在,它將創建一個新文件進行寫入。

with open('film_name.text', 'a') as f:
for one in result_all:
f.write(one + '\n')
複製代碼

存儲結果如下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!

CSV存儲

CSV文件即逗號分隔值(也稱字符分隔值,因為分隔符可以不是逗號),是一種常用的文本格式,以純文本形式存儲表格數據,包括數字或者字符。Python中已經內置CSV文件操作的模塊,只需要導入就可以進行CSV存儲操作,下面我們就將3.2.2中Xpath提取的電影名進行CSV文件存儲操作:

import requests
from lxml import etree
# 導入CSV模塊
import csv
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
url = 'http://maoyan.com/board/4'
response = requests.get(url, headers=headers)
html = response.text
html = etree.HTML(html)
result_bawangbieji = html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd[1]/div/div/div[1]/p[1]/a')
print(result_bawangbieji[0].text)
result_all = html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd/div/div/div[1]/p[1]/a')
print('該頁面全部電影名:')
for one in result_all:
print(one.text)
# 將這一頁電影名存儲至CSV文件中:
with open('film_name.csv', 'a', newline='') as f:
csv_file = csv.writer(f)
for one in result_all:
csv_file.writerow([one.text])
複製代碼

CSV文件存儲結果如下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!

MySQL 存儲

MySQL 是最流行的關係型數據庫管理系統,如果讀者沒有安裝MySQL可以通過phpstudy 2018 下載下載phpstudy快速安裝MySQL 在Python2中,連接MySQL的庫大多是使用MySQLdb,但是此庫的官方並不支持Python3,所以這裡推薦使用的庫是PyMySQL,讀者可以通過 Python+MySQL數據庫操作(PyMySQL)| Python教程™ 學習PyMYSQL操作MySQL的相關方法和實例,接下來我們就嘗試將3.2.2中Xpath提取的電影名存儲到MySQL中,沒有該模塊的讀者可以通過(win+R 輸入 cmd)pip install pymysql 安裝pymysql庫。

import requests
from lxml import etree
# 導入pymysql模塊
import pymysql
# 打開一個數據庫連接
db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='spider', use_unicode=True, charset="utf8")
# 獲取MySQL的操作遊標,利用遊標來執行SQL語句
cursor = db.cursor()
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
url = 'http://maoyan.com/board/4'
response = requests.get(url, headers=headers)
html = response.text
html = etree.HTML(html)
result_bawangbieji = html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd[1]/div/div/div[1]/p[1]/a')
print(result_bawangbieji[0].text)
result_all = html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd/div/div/div[1]/p[1]/a')
print('該頁面全部電影名:')
for one in result_all:
print(one.text)
try:
# 插入數據語句
sql = 'INSERT INTO film_infor(film_name) values (%s)'
cursor.execute(sql, (one.text))
db.commit()

except:
db.rollback()
複製代碼

MySQL存儲結果如下圖所示:

Python爬蟲入門實戰之貓眼電影數據抓取!



分享到:


相關文章: