Python爬蟲(chóng)基礎(chǔ)入門看完這一篇就學(xué)會(huì)了

前言

本文的文字及圖片來(lái)源于網(wǎng)絡(luò),僅供學(xué)習(xí)、交流使用,不具有任何商業(yè)用途,如有問(wèn)題請(qǐng)及時(shí)聯(lián)系我們以作處理。

PS:如有需要Python學(xué)習(xí)資料的小伙伴可以加點(diǎn)擊下方鏈接自行獲取

python免費(fèi)學(xué)習(xí)資料以及群交流解答點(diǎn)擊即可加入

大家好,今天我們來(lái)聊聊Python爬蟲(chóng)的基礎(chǔ)操作,反正我是這樣入門了,哈哈。



其實(shí),一開(kāi)始學(xué)python的時(shí)候,我是沖著數(shù)據(jù)處理分析去了,那個(gè)pandas什么的。后來(lái),發(fā)現(xiàn)爬蟲(chóng)挺好玩,可以解決純手工采集網(wǎng)上數(shù)據(jù)的繁瑣問(wèn)題,比如我用的比較多的爬取taptap某游戲評(píng)價(jià)內(nèi)容、某視頻網(wǎng)站某劇的彈幕、某評(píng)的店鋪信息、某牙主播信息等等。



關(guān)于爬蟲(chóng),我也只會(huì)一些比較基礎(chǔ)的操作,不過(guò)個(gè)人經(jīng)驗(yàn)上感覺(jué)這些基礎(chǔ)基本可以滿足比較常規(guī)化的需求。對(duì)于進(jìn)階的爬蟲(chóng)技巧,大家在了解熟悉爬蟲(chóng)基礎(chǔ)后自然會(huì)有進(jìn)階學(xué)習(xí)的思路與途徑。

接下來(lái),我們進(jìn)入主題吧~

0.爬蟲(chóng)基礎(chǔ)流程

把爬蟲(chóng)的過(guò)程模塊化,基本上可以歸納為以下幾個(gè)步驟:

  • [√] 分析網(wǎng)頁(yè)URL:打開(kāi)你想要爬取數(shù)據(jù)的網(wǎng)站,然后尋找真實(shí)的頁(yè)面數(shù)據(jù)URL地址;
  • [√] 請(qǐng)求網(wǎng)頁(yè)數(shù)據(jù):模擬請(qǐng)求網(wǎng)頁(yè)數(shù)據(jù),這里我們介紹requests庫(kù)的使用;
  • [√] 解析網(wǎng)頁(yè)數(shù)據(jù):根據(jù)請(qǐng)求獲得的網(wǎng)頁(yè)數(shù)據(jù)我們用不同的方式解析成我們需要用的數(shù)據(jù)(如果網(wǎng)頁(yè)數(shù)據(jù)為html源碼,我們用Beautiful Soup、xpath和re正則表達(dá)式三種解析;若網(wǎng)頁(yè)數(shù)據(jù)為json格式,我們可以直接用字典列表等基礎(chǔ)知識(shí)處理)
  • [√] 存儲(chǔ)網(wǎng)頁(yè)數(shù)據(jù):一般來(lái)說(shuō),解析后的數(shù)據(jù)是比較結(jié)構(gòu)化的,可以保存為txt、csv、json或excel等文本,亦或者可以存儲(chǔ)在數(shù)據(jù)庫(kù)如MySql、MongoDB或SqlLite中。

1.分析網(wǎng)頁(yè)URL

當(dāng)我們有一個(gè)目標(biāo)網(wǎng)站,有時(shí)候會(huì)發(fā)現(xiàn)對(duì)于靜態(tài)網(wǎng)頁(yè),我們只需要把網(wǎng)頁(yè)地址欄中的URL傳到get請(qǐng)求中就可以直接取到網(wǎng)頁(yè)的數(shù)據(jù)。但如果這是動(dòng)態(tài)網(wǎng)頁(yè),我們便無(wú)法通過(guò)簡(jiǎn)單的傳遞網(wǎng)頁(yè)地址欄的URL給get請(qǐng)求來(lái)獲取網(wǎng)頁(yè)數(shù)據(jù),往往這個(gè)時(shí)候,我們進(jìn)行翻頁(yè)的時(shí)候還會(huì)發(fā)現(xiàn)網(wǎng)頁(yè)地址欄中的URL是不會(huì)發(fā)生變化的。

接下來(lái),我們來(lái)分別介紹這兩種情況下如何獲取真實(shí)的頁(yè)面數(shù)據(jù)URL地址。

1.1 靜態(tài)網(wǎng)頁(yè)

對(duì)于靜態(tài)網(wǎng)頁(yè)來(lái)說(shuō),其實(shí)網(wǎng)頁(yè)地址欄中的URL就是我們需要的。

以 貝殼二手房網(wǎng)(https://bj.ke.com/ershoufang/) 為例,我們可以看到進(jìn)行翻頁(yè)(如到第2頁(yè))的時(shí)候網(wǎng)頁(yè)地址欄的URL變?yōu)榱?https://bj.ke.com/ershoufang/pg2/)。類型這種情況,多半就是靜態(tài)網(wǎng)頁(yè)了,而且翻頁(yè)的URL規(guī)律十分明顯。

1.2 動(dòng)態(tài)網(wǎng)頁(yè)

對(duì)于動(dòng)態(tài)網(wǎng)頁(yè)來(lái)說(shuō),我們一般可以通過(guò)以下幾個(gè)步驟找到真實(shí)URL地址:

1.需要按“F12”進(jìn)入到瀏覽器的開(kāi)發(fā)者模式;
2.點(diǎn)擊“Network”—>XHR或JS或者你全部查找看;
3.進(jìn)行翻頁(yè)(可能是點(diǎn)擊下一頁(yè)或者下滑加載更多);
4.觀察第2步中name模塊的內(nèi)容變化,尋找。

以 虎牙星秀區(qū)(https://www.huya.com/g/xingxiu) 為例,我們可以看到進(jìn)行翻頁(yè)(如到第2頁(yè))的時(shí)候網(wǎng)頁(yè)地址欄的URL沒(méi)有發(fā)生任何改變。

為了便于找到真實(shí)的URL地址,我們可以在開(kāi)發(fā)者模式中找以下截圖中的幾點(diǎn),preview是預(yù)覽結(jié)果,可以便于我們進(jìn)行匹配定位具體的Name。



當(dāng)我們定位到具體的Name后,右側(cè)選擇Headers可以查看到請(qǐng)求網(wǎng)頁(yè)需要的相關(guān)參數(shù)信息,而且比較好擬清其變化規(guī)律。以虎牙星秀為例,其真實(shí)URL地址及變化規(guī)律如下:



真實(shí)URL地址

2.請(qǐng)求網(wǎng)頁(yè)數(shù)據(jù)

當(dāng)我們確定了真實(shí)數(shù)據(jù)的URL后,這里便可以用requests的get或post方法進(jìn)行請(qǐng)求網(wǎng)頁(yè)數(shù)據(jù)。

關(guān)于requests庫(kù)的更多使用方式,大家可以前往(https://requests.readthedocs.io/zh_CN/latest/)查看。

2.1 發(fā)送get請(qǐng)求

In [1]: import requests

In [2]: url = 'https://bj.ke.com/ershoufang/'

In [3]: r = requests.get(url)

In [4]: type(r)
Out[4]: requests.models.Response

In [5]: r.status_code
Out[5]: 200

我們得到的是一個(gè)Response對(duì)象,如果我們想要獲取網(wǎng)頁(yè)數(shù)據(jù),可以使用text或content屬性來(lái)獲取,另外如果獲取的網(wǎng)頁(yè)數(shù)據(jù)是json格式的則可以使用Requests 中內(nèi)置的 json()解碼器方法,助你處理json 數(shù)據(jù)。

  • r.text:字符串類型的數(shù)據(jù),一般網(wǎng)頁(yè)數(shù)據(jù)為文本類用此屬性
  • r.content:二進(jìn)制類型的數(shù)據(jù),一般網(wǎng)頁(yè)數(shù)據(jù)為視頻或者圖片時(shí)用此屬性
  • r.json():json數(shù)據(jù)解碼,一般網(wǎng)頁(yè)數(shù)據(jù)為json格式時(shí)用此方法
    對(duì)于一些動(dòng)態(tài)網(wǎng)頁(yè),請(qǐng)求的網(wǎng)址是基礎(chǔ)url和關(guān)鍵字參數(shù)組合而成,這個(gè)時(shí)候我們可以使用 params 關(guān)鍵字參數(shù),以一個(gè)字符串字典來(lái)提供這些參數(shù)。
In [6]: url = 'https://www.huya.com/cache.php'
   ...: parames = {
   ...:     'm': 'LiveList',
   ...:     'do': 'getLiveListByPage',
   ...:     'gameId': 1663,
   ...:     'tagAll': 0,
   ...:     'page': 2, # 翻頁(yè)變化的就是這個(gè)參數(shù)
   ...:     }
   ...: 
   ...: r = requests.get(url, params=parames)

In [7]: r.url
Out[7]: 'https://www.huya.com/cache.php?m=LiveList&do=getLiveListByPage&gameId=1663&tagAll=0&page=2'

2.2 發(fā)送post請(qǐng)求

通常,你想要發(fā)送一些編碼為表單形式的數(shù)據(jù)——非常像一個(gè) HTML 表單。要實(shí)現(xiàn)這個(gè),只需簡(jiǎn)單地傳遞一個(gè)字典給 data 參數(shù)。你的數(shù)據(jù)字典在發(fā)出請(qǐng)求時(shí)會(huì)自動(dòng)編碼為表單形式:

>>> payload = {'key1': 'value1', 'key2': 'value2'}

>>> r = requests.post("http://httpbin.org/post", data=payload)

很多時(shí)候你想要發(fā)送的數(shù)據(jù)并非編碼為表單形式的。如果你傳遞一個(gè) string 而不是一個(gè) dict,那么數(shù)據(jù)會(huì)被直接發(fā)布出去。

>>> import json

>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}

>>> r = requests.post(url, data=json.dumps(payload))

此處除了可以自行對(duì) dict 進(jìn)行編碼,你還可以使用 json 參數(shù)直接傳遞,然后它就會(huì)被自動(dòng)編碼。

>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}

>>> r = requests.post(url, json=payload)

2.3 定制請(qǐng)求頭

在模擬請(qǐng)求時(shí),如果不設(shè)置請(qǐng)求頭的話是比較容易被網(wǎng)站發(fā)現(xiàn)是來(lái)自爬蟲(chóng)腳本,一些網(wǎng)站會(huì)對(duì)這種模擬請(qǐng)求進(jìn)行拒絕。因此我們可以簡(jiǎn)單設(shè)置一下請(qǐng)求頭做偽裝,一般是設(shè)置瀏覽器。

headers = {
     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36",
     }
r = requests.get(url, headers=headers)

其實(shí),對(duì)于請(qǐng)求頭還可以設(shè)置很多參數(shù),具體大家可以在實(shí)際爬蟲(chóng)過(guò)程中在開(kāi)發(fā)者模式看看里面的請(qǐng)求頭模塊進(jìn)行分析處理。


虎牙星秀請(qǐng)求頭

2.4 響應(yīng)碼

我們?cè)?2.1 中看到獲取響應(yīng)碼的是通過(guò) r.status_code屬性,一般來(lái)說(shuō)如果 返回 數(shù)字 200,則表示成功獲取了網(wǎng)頁(yè)數(shù)據(jù)。

響應(yīng)碼分為五種類型,由它們的第一位數(shù)字表示:1xx:信息,請(qǐng)求收到,繼續(xù)處理 2xx:成功,行為被成功地接受、理解和采納 3xx:重定向,為了完成請(qǐng)求,必須進(jìn)一步執(zhí)行的動(dòng)作 4xx:客戶端錯(cuò)誤,請(qǐng)求包含語(yǔ)法錯(cuò)誤或者請(qǐng)求無(wú)法實(shí)現(xiàn) 5xx:服務(wù)器錯(cuò)誤,服務(wù)器不能實(shí)現(xiàn)一種明顯無(wú)效的請(qǐng)求

3.解析數(shù)據(jù)

上面有提到我們請(qǐng)求的網(wǎng)頁(yè)數(shù)據(jù)有Html源碼文本或者是json字符串文本,兩者的解析方式不同。以下我們分別進(jìn)行簡(jiǎn)單說(shuō)明,大家在實(shí)際操作中視情況而定即可。

3.1 網(wǎng)頁(yè)html文本解析

對(duì)于網(wǎng)頁(yè)html文本來(lái)說(shuō),這里介紹Beautiful Soup、xpath和re正則表達(dá)式三種解析方法。

以貝殼二手房最新房源(https://bj.ke.com/ershoufang/co32/)為例,其html源碼如下,我們通過(guò)get請(qǐng)求后的數(shù)據(jù)進(jìn)行解析。

3.1.1 Beautiful Soup

關(guān)于Beautiful Soup庫(kù)的更多使用方式,大家可以前往查看(https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/)

首先安裝pip install beautifulsoup4。

我們將網(wǎng)頁(yè)html文本內(nèi)容r.text當(dāng)作第一個(gè)參數(shù)傳給BeautifulSoup對(duì)象,該對(duì)象的第二個(gè)參數(shù)為解析器的類型(這里使用lxml),此時(shí)就完成了BeaufulSoup對(duì)象的初始化。然后,將這個(gè)對(duì)象賦值給soup變量。

from bs4 import BeautifulSoup
import requests

url = 'https://bj.ke.com/ershoufang/co32/'
r = requests.get(url)
soup = BeautifulSoup(r.text, 'lxml')

獲取房源的名稱的代碼如下:

# 獲取全部房源 所在的節(jié)點(diǎn)
sellList = soup.find(class_="sellListContent")
# 獲取全部房源節(jié)點(diǎn)列表
lis = sellList.find_all('li',class_="clear")
# 選取第一個(gè)房源節(jié)點(diǎn)
div = lis[0].find('div',class_="info clear")
# 采集房源名稱
title = div.find('div',class_="title")
print(title.text)
明春西園 2室1廳 南 北

3.1.2 xpath

XPath,全稱 XML Path Language,即 XML 路徑語(yǔ)言,它是一門在 XML 文檔中查找信息的語(yǔ)言。

首先安裝lxmlpip install lxml。

常見(jiàn)的規(guī)則如下:



首先導(dǎo)入 lxml 庫(kù)的 etree 模塊,然后聲明一段 HTML 文本,調(diào)用 HTML 類進(jìn)行初始化,成功構(gòu)造一個(gè) XPath 解析對(duì)象。

from lxml import etree
import requests

url = 'https://bj.ke.com/ershoufang/co32/'
r = requests.get(url)
html = etree.HTML(r.text)

通過(guò)copy獲取的xpath://*[@id="beike"]/div[1]/div[4]/div[1]/div[4]/ul/li[1]/div/div[1]/a

# 獲取 全部房源所在節(jié)點(diǎn) ul,根據(jù)屬性匹配精準(zhǔn)查找
ul = html.xpath('.//ul[@class="sellListContent"]')[0]
# 獲取房源列表
lis = ul.xpath('.//li[@class="clear"]')
# 選取第一個(gè)房源節(jié)點(diǎn)
li = lis[0]
# 獲取其房源名稱
li.xpath('./div/div[1]/a/text()')
['明春西園 2室1廳 南 北']

3.1.3 re正則

關(guān)于re正則解析網(wǎng)頁(yè)html大家也可以前往查看此前發(fā)布的文章《對(duì)著爬蟲(chóng)網(wǎng)頁(yè)HTML學(xué)習(xí)Python正則表達(dá)式re》。

# 找到房源名稱所在的前后字符,然后組成正則表達(dá)式
re.findall(r'<a class="VIEWDATA CLICKDATA maidian-detail" title="(.*?)"',r.text,re.S)[0]
'明春西園 2室1廳 南 北'

3.2 json文本解析

在requests提供了r.json(),可以用于json數(shù)據(jù)解碼,一般網(wǎng)頁(yè)數(shù)據(jù)為json格式時(shí)用此方法。除此之外,還可以通過(guò)json.loads()和eval()方法進(jìn)行處理。

url = 'https://www.huya.com/cache.php'
parames = {
     'm': 'LiveList',
     'do': 'getLiveListByPage',
     'gameId': 1663,
     'tagAll': 0,
     'page': 2, # 翻頁(yè)變化的就是這個(gè)參數(shù)
     }

r = requests.get(url, params=parames)
data = r.json()
type(data)
dict

如此解析后得到的數(shù)據(jù)就是字典,然后我們?cè)诳纯醋值渲心男┳侄问俏覀冃枰?,取出即可?/p>

4.存儲(chǔ)數(shù)據(jù)

當(dāng)我們獲取了到想要的數(shù)據(jù)后,便可以寫入本地了。

對(duì)于文本類數(shù)據(jù),可以通過(guò)csv模塊或pandas模塊進(jìn)行寫入到本地csv文件或excel文件;同時(shí)也可以用pymysql模塊寫入到數(shù)據(jù)庫(kù)或者sqlite寫入到本地?cái)?shù)據(jù)庫(kù)。

對(duì)于視頻或者圖片,可以open一個(gè)文件然后寫入二進(jìn)制內(nèi)容后保存本地亦可。

關(guān)于存儲(chǔ)數(shù)據(jù)大家可以結(jié)合實(shí)際案例進(jìn)行學(xué)習(xí)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容