自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python爬蟲(chóng)入門(mén)教程!手把手教會(huì)你爬取網(wǎng)頁(yè)數(shù)據(jù)

開(kāi)發(fā) 后端
其實(shí)在當(dāng)今社會(huì),網(wǎng)絡(luò)上充斥著大量有用的數(shù)據(jù),我們只需要耐心的觀察,再加上一些技術(shù)手段,就可以獲取到大量的有價(jià)值數(shù)據(jù)。這里的“技術(shù)手段”就是網(wǎng)絡(luò)爬蟲(chóng)。今天就給大家分享一篇爬蟲(chóng)基礎(chǔ)知識(shí)和入門(mén)教程。

其實(shí)在當(dāng)今社會(huì),網(wǎng)絡(luò)上充斥著大量有用的數(shù)據(jù),我們只需要耐心的觀察,再加上一些技術(shù)手段,就可以獲取到大量的有價(jià)值數(shù)據(jù)。這里的“技術(shù)手段”就是網(wǎng)絡(luò)爬蟲(chóng)。今天就給大家分享一篇爬蟲(chóng)基礎(chǔ)知識(shí)和入門(mén)教程:

[[348531]]

什么是爬蟲(chóng)?

爬蟲(chóng)就是自動(dòng)獲取網(wǎng)頁(yè)內(nèi)容的程序,例如搜索引擎,Google,Baidu 等,每天都運(yùn)行著龐大的爬蟲(chóng)系統(tǒng),從全世界的網(wǎng)站中爬蟲(chóng)數(shù)據(jù),供用戶檢索時(shí)使用。

爬蟲(chóng)流程

其實(shí)把網(wǎng)絡(luò)爬蟲(chóng)抽象開(kāi)來(lái)看,它無(wú)外乎包含如下幾個(gè)步驟

  • 模擬請(qǐng)求網(wǎng)頁(yè)。模擬瀏覽器,打開(kāi)目標(biāo)網(wǎng)站。
  • 獲取數(shù)據(jù)。打開(kāi)網(wǎng)站之后,就可以自動(dòng)化的獲取我們所需要的網(wǎng)站數(shù)據(jù)。
  • 保存數(shù)據(jù)。拿到數(shù)據(jù)之后,需要持久化到本地文件或者數(shù)據(jù)庫(kù)等存儲(chǔ)設(shè)備中。

那么我們?cè)撊绾问褂?Python 來(lái)編寫(xiě)自己的爬蟲(chóng)程序呢,在這里我要重點(diǎn)介紹一個(gè) Python 庫(kù):Requests。

Requests 使用

Requests 庫(kù)是 Python 中發(fā)起 HTTP 請(qǐng)求的庫(kù),使用非常方便簡(jiǎn)單。

模擬發(fā)送 HTTP 請(qǐng)求

發(fā)送 GET 請(qǐng)求

當(dāng)我們用瀏覽器打開(kāi)豆瓣首頁(yè)時(shí),其實(shí)發(fā)送的最原始的請(qǐng)求就是 GET 請(qǐng)求

 

  1. import requests 
  2. res = requests.get('http://www.douban.com'
  3. print(res) 
  4. print(type(res)) 
  5. >>> 
  6. <Response [200]> 
  7. <class 'requests.models.Response'

可以看到,我們得到的是一個(gè) Response 對(duì)象

如果我們要獲取網(wǎng)站返回的數(shù)據(jù),可以使用 text 或者 content 屬性來(lái)獲取

text:是以字符串的形式返回?cái)?shù)據(jù)

content:是以二進(jìn)制的方式返回?cái)?shù)據(jù)

 

  1. print(type(res.text)) 
  2. print(res.text) 
  3. >>> 
  4. <class 'str'> <!DOCTYPE HTML> 
  5. <html lang="zh-cmn-Hans" class=""
  6. <head> 
  7. <meta charset="UTF-8"
  8. <meta name="google-site-verification" content="ok0wCgT20tBBgo9_zat2iAcimtN4Ftf5ccsh092Xeyw" /> 
  9. <meta name="description" content="提供圖書(shū)、電影、音樂(lè)唱片的推薦、評(píng)論和價(jià)格比較,以及城市獨(dú)特的文化生活。"
  10. <meta name="keywords" content="豆瓣,廣播,登陸豆瓣">..... 

發(fā)送 POST 請(qǐng)求

對(duì)于 POST 請(qǐng)求,一般就是提交一個(gè)表單

  1. r = requests.post('http://www.xxxx.com', data={"key""value"}) 

data 當(dāng)中,就是需要傳遞的表單信息,是一個(gè)字典類型的數(shù)據(jù)。

header 增強(qiáng)

對(duì)于有些網(wǎng)站,會(huì)拒絕掉沒(méi)有攜帶 header 的請(qǐng)求的,所以需要做一些 header 增強(qiáng)。比如:UA,Cookie,host 等等信息。

 

  1. header = {"User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
  2.          "Cookie""your cookie"
  3. res = requests.get('http://www.xxx.com', headers=header) 

解析 HTML

現(xiàn)在我們已經(jīng)獲取到了網(wǎng)頁(yè)返回的數(shù)據(jù),即 HTML 代碼,下面就需要解析 HTML,來(lái)提取其中有效的信息。

BeautifulSoup

BeautifulSoup 是 Python 的一個(gè)庫(kù),最主要的功能是從網(wǎng)頁(yè)解析數(shù)據(jù)。

  1. from bs4 import BeautifulSoup  # 導(dǎo)入 BeautifulSoup 的方法 
  2. # 可以傳入一段字符串,或者傳入一個(gè)文件句柄。一般都會(huì)先用 requests 庫(kù)獲取網(wǎng)頁(yè)內(nèi)容,然后使用 soup 解析。 
  3. soup = BeautifulSoup(html_doc,'html.parser')  # 這里一定要指定解析器,可以使用默認(rèn)的 html,也可以使用 lxml。 
  4. print(soup.prettify())  # 按照標(biāo)準(zhǔn)的縮進(jìn)格式輸出獲取的 soup 內(nèi)容。 

BeautifulSoup 的一些簡(jiǎn)單用法

 

  1. print(soup.title)  # 獲取文檔的 title 
  2. print(soup.title.name)  # 獲取 title 的 name 屬性 
  3. print(soup.title.string)  # 獲取 title 的內(nèi)容 
  4. print(soup.p)  # 獲取文檔中第一個(gè) p 節(jié)點(diǎn) 
  5. print(soup.p['class'])  # 獲取第一個(gè) p 節(jié)點(diǎn)的 class 內(nèi)容 
  6. print(soup.find_all('a'))  # 獲取文檔中所有的 a 節(jié)點(diǎn),返回一個(gè) list 
  7. print(soup.find_all('span', attrs={'style'"color:#ff0000"}))  # 獲取文檔中所有的 span 且 style 符合規(guī)則的節(jié)點(diǎn),返回一個(gè) list 

具體的用法和效果,我會(huì)在后面的實(shí)戰(zhàn)中詳細(xì)說(shuō)明。

XPath 定位

XPath 是 XML 的路徑語(yǔ)言,是通過(guò)元素和屬性進(jìn)行導(dǎo)航定位的。幾種常用的表達(dá)式

表達(dá)式含義node選擇 node 節(jié)點(diǎn)的所有子節(jié)點(diǎn)/從根節(jié)點(diǎn)選取//選取所有當(dāng)前節(jié)點(diǎn).當(dāng)前節(jié)點(diǎn)..父節(jié)點(diǎn)@屬性選取text()當(dāng)前路徑下的文本內(nèi)容

一些簡(jiǎn)單的例子

 

  1. xpath('node')  # 選取 node 節(jié)點(diǎn)的所有子節(jié)點(diǎn) 
  2. xpath('/div')  # 從根節(jié)點(diǎn)上選取 div 元素 
  3. xpath('//div')  # 選取所有 div 元素 
  4. xpath('./div')  # 選取當(dāng)前節(jié)點(diǎn)下的 div 元素 
  5. xpath('//@id')  # 選取所有 id 屬性的節(jié)點(diǎn) 

當(dāng)然,XPath 非常強(qiáng)大,但是語(yǔ)法也相對(duì)復(fù)雜,不過(guò)我們可以通過(guò) Chrome 的開(kāi)發(fā)者工具來(lái)快速定位到元素的 xpath,如下圖

 

Python爬蟲(chóng)入門(mén)教程!手把手教會(huì)你爬取網(wǎng)頁(yè)數(shù)據(jù)

得到的 xpath 為

  1. //*[@id="anony-nav"]/div[1]/ul/li[1]/a 

在實(shí)際的使用過(guò)程中,到底使用 BeautifulSoup 還是 XPath,完全取決于個(gè)人喜好,哪個(gè)用起來(lái)更加熟練方便,就使用哪個(gè)。

爬蟲(chóng)實(shí)戰(zhàn):爬取豆瓣海報(bào)

我們可以從豆瓣影人頁(yè),進(jìn)入都影人對(duì)應(yīng)的影人圖片頁(yè)面,比如以劉濤為例子,她的影人圖片頁(yè)面地址為

  • https://movie.douban.com/celebrity/1011562/photos/

 

Python爬蟲(chóng)入門(mén)教程!手把手教會(huì)你爬取網(wǎng)頁(yè)數(shù)據(jù)

下面我們就來(lái)分析下這個(gè)網(wǎng)頁(yè)

目標(biāo)網(wǎng)站頁(yè)面分析

注意:網(wǎng)絡(luò)上的網(wǎng)站頁(yè)面構(gòu)成總是會(huì)變化的,所以這里你需要學(xué)會(huì)分析的方法,以此類推到其他網(wǎng)站。正所謂授人以魚(yú)不如授人以漁,就是這個(gè)原因。

Chrome 開(kāi)發(fā)者工具

Chrome 開(kāi)發(fā)者工具(按 F12 打開(kāi)),是分析網(wǎng)頁(yè)的絕佳利器,一定要好好使用。

我們?cè)谌我庖粡垐D片上右擊鼠標(biāo),選擇“檢查”,可以看到同樣打開(kāi)了“開(kāi)發(fā)者工具”,而且自動(dòng)定位到了該圖片所在的位置

 

Python爬蟲(chóng)入門(mén)教程!手把手教會(huì)你爬取網(wǎng)頁(yè)數(shù)據(jù)

可以清晰的看到,每張圖片都是保存在 li 標(biāo)簽中的,圖片的地址保存在 li 標(biāo)簽中的 img 中。

知道了這些規(guī)律后,我們就可以通過(guò) BeautifulSoup 或者 XPath 來(lái)解析 HTML 頁(yè)面,從而獲取其中的圖片地址。

代碼編寫(xiě)

我們只需要短短的幾行代碼,就能完成圖片 url 的提取

 

  1. import requests 
  2. from bs4 import BeautifulSoup  
  3.  
  4. url = 'https://movie.douban.com/celebrity/1011562/photos/' 
  5. res = requests.get(url).text 
  6. content = BeautifulSoup(res, "html.parser"
  7. data = content.find_all('div', attrs={'class''cover'}) 
  8. picture_list = [] 
  9. for d in data: 
  10.     plist = d.find('img')['src'
  11.     picture_list.append(plist) 
  12. print(picture_list) 
  13. >>> 
  14. ['https://img1.doubanio.com/view/photo/m/public/p2564834267.jpg''https://img1.doubanio.com/view/photo/m/public/p860687617.jpg''https://img1.doubanio.com/view/photo/m/public/p2174001857.jpg''https://img1.doubanio.com/view/photo/m/public/p1563789129.jpg''https://img3.doubanio.com/view/photo/m/public/p2363429946.jpg''https://img1.doubanio.com/view/photo/m/public/p2382591759.jpg''https://img3.doubanio.com/view/photo/m/public/p2363269182.jpg''https://img1.doubanio.com/view/photo/m/public/p1959495269.jpg''https://img3.doubanio.com/view/photo/m/public/p2356638830.jpg''https://img3.doubanio.com/view/photo/m/public/p1959495471.jpg''https://img3.doubanio.com/view/photo/m/public/p1834379290.jpg''https://img3.doubanio.com/view/photo/m/public/p2325385303.jpg''https://img3.doubanio.com/view/photo/m/public/p2361707270.jpg''https://img3.doubanio.com/view/photo/m/public/p2325385321.jpg''https://img3.doubanio.com/view/photo/m/public/p2196488184.jpg''https://img1.doubanio.com/view/photo/m/public/p2186019528.jpg''https://img1.doubanio.com/view/photo/m/public/p2363270277.jpg''https://img3.doubanio.com/view/photo/m/public/p2325240501.jpg''https://img1.doubanio.com/view/photo/m/public/p2258657168.jpg''https://img1.doubanio.com/view/photo/m/public/p2319710627.jpg''https://img3.doubanio.com/view/photo/m/public/p2319710591.jpg''https://img3.doubanio.com/view/photo/m/public/p2311434791.jpg''https://img1.doubanio.com/view/photo/m/public/p2363270708.jpg''https://img3.doubanio.com/view/photo/m/public/p2258657185.jpg''https://img3.doubanio.com/view/photo/m/public/p2166193915.jpg''https://img3.doubanio.com/view/photo/m/public/p2363265595.jpg''https://img3.doubanio.com/view/photo/m/public/p2312085755.jpg''https://img3.doubanio.com/view/photo/m/public/p2311434790.jpg''https://img3.doubanio.com/view/photo/m/public/p2276569205.jpg''https://img1.doubanio.com/view/photo/m/public/p2165332728.jpg'

可以看到,是非常干凈的列表,里面存儲(chǔ)了海報(bào)地址。

但是這里也只是一頁(yè)海報(bào)的數(shù)據(jù),我們觀察頁(yè)面發(fā)現(xiàn)它有好多分頁(yè),如何處理分頁(yè)呢。

 

Python爬蟲(chóng)入門(mén)教程!手把手教會(huì)你爬取網(wǎng)頁(yè)數(shù)據(jù)

分頁(yè)處理

我們點(diǎn)擊第二頁(yè),看看瀏覽器 url 的變化

  • https://movie.douban.com/celebrity/1011562/photos/?type=C&start=30&sortby=like&size=a&subtype=a

發(fā)現(xiàn)瀏覽器 url 增加了幾個(gè)參數(shù)

再點(diǎn)擊第三頁(yè),繼續(xù)觀察 url

  • https://movie.douban.com/celebrity/1011562/photos/?type=C&start=60&sortby=like&size=a&subtype=a

通過(guò)觀察可知,這里的參數(shù),只有 start 是變化的,即為變量,其余參數(shù)都可以按照常理來(lái)處理

同時(shí)還可以知道,這個(gè) start 參數(shù)應(yīng)該是起到了類似于 page 的作用,start = 30 是第二頁(yè),start = 60 是第三頁(yè),依次類推,最后一頁(yè)是 start = 420。

于是我們處理分頁(yè)的代碼也呼之欲出了

首先將上面處理 HTML 頁(yè)面的代碼封裝成函數(shù)

 

  1. def get_poster_url(res): 
  2.     content = BeautifulSoup(res, "html.parser"
  3.     data = content.find_all('div', attrs={'class''cover'}) 
  4.     picture_list = [] 
  5.     for d in data: 
  6.         plist = d.find('img')['src'
  7.         picture_list.append(plist) 
  8.     return picture_list 

然后我們?cè)诹硪粋€(gè)函數(shù)中處理分頁(yè)和調(diào)用上面的函數(shù)

 

  1. def fire(): 
  2.     page = 0 
  3.     for i in range(0, 450, 30): 
  4.         print("開(kāi)始爬取第 %s 頁(yè)" % page) 
  5.         url = 'https://movie.douban.com/celebrity/1011562/photos/?type=C&start={}&sortby=like&size=a&subtype=a'.format(i) 
  6.         res = requests.get(url).text 
  7.         data = get_poster_url(res) 
  8.         page += 1 

此時(shí),我們所有的海報(bào)數(shù)據(jù)都保存在了 data 變量中,現(xiàn)在就需要一個(gè)下載器來(lái)保存海報(bào)了

 

  1. def download_picture(pic_l): 
  2.     if not os.path.exists(r'picture'): 
  3.         os.mkdir(r'picture'
  4.     for i in pic_l: 
  5.         pic = requests.get(i) 
  6.         p_name = i.split('/')[7] 
  7.         with open('picture\\' + p_name, 'wb') as f: 
  8.             f.write(pic.content) 

再增加下載器到 fire 函數(shù),此時(shí)為了不是請(qǐng)求過(guò)于頻繁而影響豆瓣網(wǎng)的正常訪問(wèn),設(shè)置 sleep time 為1秒

 

  1. def fire(): 
  2.     page = 0 
  3.     for i in range(0, 450, 30): 
  4.         print("開(kāi)始爬取第 %s 頁(yè)" % page) 
  5.         url = 'https://movie.douban.com/celebrity/1011562/photos/?type=C&start={}&sortby=like&size=a&subtype=a'.format(i) 
  6.         res = requests.get(url).text 
  7.         data = get_poster_url(res) 
  8.         download_picture(data) 
  9.         page += 1 
  10.         time.sleep(1) 

下面就執(zhí)行 fire 函數(shù),等待程序運(yùn)行完成后,當(dāng)前目錄下會(huì)生成一個(gè) picture 的文件夾,里面保存了我們下載的所有海報(bào)

 

Python爬蟲(chóng)入門(mén)教程!手把手教會(huì)你爬取網(wǎng)頁(yè)數(shù)據(jù)

核心代碼講解

下面再來(lái)看下完整的代碼

 

  1. import requests 
  2. from bs4 import BeautifulSoup 
  3. import time 
  4. import osdef fire(): 
  5.     page = 0 
  6.     for i in range(0, 450, 30): 
  7.         print("開(kāi)始爬取第 %s 頁(yè)" % page) 
  8.         url = 'https://movie.douban.com/celebrity/1011562/photos/?type=C&start={}&sortby=like&size=a&subtype=a'.format(i) 
  9.         res = requests.get(url).text 
  10.         data = get_poster_url(res) 
  11.         download_picture(data) 
  12.         page += 1 
  13.         time.sleep(1)def get_poster_url(res): 
  14.     content = BeautifulSoup(res, "html.parser"
  15.     data = content.find_all('div', attrs={'class''cover'}) 
  16.     picture_list = [] 
  17.     for d in data: 
  18.         plist = d.find('img')['src'
  19.         picture_list.append(plist) 
  20.     return picture_listdef download_picture(pic_l): 
  21.     if not os.path.exists(r'picture'): 
  22.         os.mkdir(r'picture'
  23.     for i in pic_l: 
  24.         pic = requests.get(i) 
  25.         p_name = i.split('/')[7] 
  26.         with open('picture\\' + p_name, 'wb') as f: 
  27.             f.write(pic.content)if __name__ == '__main__'
  28.     fire() 

fire 函數(shù)

這是一個(gè)主執(zhí)行函數(shù),使用 range 函數(shù)來(lái)處理分頁(yè)。

  • range 函數(shù)可以快速的創(chuàng)建整數(shù)列表,在 for 循環(huán)時(shí)及其好用。函數(shù)中的0代表從0開(kāi)始計(jì)數(shù),450代表一直迭代到450,不包含450,30代表步長(zhǎng),即每次遞增的數(shù)字間隔。range(0, 450, 30),依次會(huì)輸出:0,30,60,90 …
  • format 函數(shù),是一種字符串格式化方式
  • time.sleep(1) 即為暫停1秒鐘

get_poster_url 函數(shù)

這個(gè)就是解析 HTML 的函數(shù),使用的是 BeautifulSoup

  • 通過(guò) find_all 方法查找所有 class 為 “cover” 的 div 元素,返回的是一個(gè)列表
  • 使用 for 循環(huán),循環(huán)上一步拿到的列表,取出 src 的內(nèi)容,append 到列表中
  • append 是列表的一個(gè)方法,可以在列表后面追加元素

download_picture 函數(shù)

簡(jiǎn)易圖片下載器

  • 首先判斷當(dāng)前目錄下是否存在 picture 文件夾,os.path.exists
  • os 庫(kù)是非常常用用來(lái)操作系統(tǒng)相關(guān)的命令庫(kù),os.mkdir 就是創(chuàng)建文件夾
  • split 用于切割字符串,取出角標(biāo)為7的元素,作為存儲(chǔ)圖片的名稱
  • with 方法用來(lái)快速打開(kāi)文件,打開(kāi)的進(jìn)程可以自行關(guān)閉文件句柄,而不再需要手動(dòng)執(zhí)行 f.close() 關(guān)閉文件

總結(jié)

本節(jié)講解了爬蟲(chóng)的基本流程以及需要用到的 Python 庫(kù)和方法,并通過(guò)一個(gè)實(shí)際的例子完成了從分析網(wǎng)頁(yè),到數(shù)據(jù)存儲(chǔ)的全過(guò)程。其實(shí)爬蟲(chóng),無(wú)外乎模擬請(qǐng)求,解析數(shù)據(jù),保存數(shù)據(jù)。

當(dāng)然有的時(shí)候,網(wǎng)站還會(huì)設(shè)置各種反爬機(jī)制,比如 cookie 校驗(yàn),請(qǐng)求頻度檢查,非瀏覽器訪問(wèn)限制,JS 混淆等等,這個(gè)時(shí)候就需要用到反反爬技術(shù)了,比如抓取 cookie 放到 headers 中,使用代理 IP 訪問(wèn),使用 Selenium 模擬瀏覽器等待方式。

由于本課程不是專門(mén)的爬蟲(chóng)課,這些技能就留待你自己去探索挖掘啦。

 

Python爬蟲(chóng)入門(mén)教程!手把手教會(huì)你爬取網(wǎng)頁(yè)數(shù)據(jù)

 

責(zé)任編輯:未麗燕 來(lái)源: 蘿卜大雜燴
相關(guān)推薦

2009-12-11 09:04:10

Windows搭建Li

2020-10-12 08:19:43

Python爬蟲(chóng)網(wǎng)頁(yè)數(shù)據(jù)

2021-06-16 09:02:43

Pythonjieba分詞Python基礎(chǔ)

2009-12-21 11:36:24

Linux啟動(dòng)加密

2009-10-22 15:23:32

VB.NET函數(shù)

2021-12-09 10:24:47

Javascript 高階函數(shù)前端

2018-05-16 13:50:30

Python網(wǎng)絡(luò)爬蟲(chóng)Scrapy

2021-07-03 09:04:22

XPathPython免費(fèi)代理IP

2010-07-30 10:41:23

DB2打補(bǔ)丁

2020-12-13 11:38:09

Go語(yǔ)言clac包

2021-04-30 09:05:37

爬蟲(chóng)框架數(shù)據(jù)

2021-05-08 08:04:05

Python爬取素材

2020-03-08 22:06:16

Python數(shù)據(jù)IP

2020-07-10 08:24:18

Python開(kāi)發(fā)工具

2020-11-10 09:11:02

采集數(shù)據(jù)

2021-02-17 09:23:31

Python百度搜索

2018-05-22 15:30:30

Python網(wǎng)絡(luò)爬蟲(chóng)分布式爬蟲(chóng)

2018-05-14 16:34:08

Python網(wǎng)絡(luò)爬蟲(chóng)Scrapy

2022-06-30 08:13:44

PythonWeb編程語(yǔ)言

2018-05-16 15:46:06

Python網(wǎng)絡(luò)爬蟲(chóng)PhantomJS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)