圖解爬蟲,用幾個最簡單的例子帶你入門Python爬蟲

1、前言

爬蟲一直是Python的一大應用場景,差很少每門語言均可以寫爬蟲,可是程序員們卻獨愛Python。之因此偏心Python就是由於她簡潔的語法,咱們使用Python能夠很簡單的寫出一個爬蟲程序。本篇博客將以Python語言,用幾個很是簡單的例子帶你們入門Python爬蟲。css

2、網絡爬蟲

若是把咱們的因特網比做一張複雜的蜘蛛網的話,那咱們的爬蟲就是一個蜘,咱們可讓這個蜘蛛在網上任意爬行,在網中尋找對咱們有價值的「獵物」。html

首先咱們的網絡爬蟲是創建在網絡之上的,因此網絡爬蟲的基礎就是網絡請求。在咱們平常生活中,咱們會使用瀏覽器瀏覽網頁,咱們在網址欄輸入一個網址,點擊回車在幾秒時間後就能顯示一個網頁。咱們表面上是點擊了幾個按鈕,實際上瀏覽器幫咱們完成了一些了的操做,具體操做有以下幾個:前端

1.向服務器發送網絡請求2.瀏覽器接收並處理你的請求3.瀏覽器返回你須要的數據4.瀏覽器解析數據,並以網頁的形式展示出來python

咱們能夠將上面的過程類比咱們的平常購物:程序員

1.和老闆說我要杯珍珠奶茶2.老闆在店裏看看有沒有你要的東西3.老闆拿出作奶茶的材料4.老闆將材料作成奶茶並給你正則表達式

上面買奶茶的例子雖然有些不恰當的地方,可是我以爲已經能很好的解釋什麼是網絡請求了。在知道網絡請求是什麼以後,咱們就能夠來了解一下什麼是爬蟲了。實際上爬蟲也是網絡請求,一般狀況下咱們經過瀏覽器,而咱們的爬蟲則是經過程序來模擬網絡請求這一過程。可是這種基礎的網絡請求還算不上是爬蟲,爬蟲一般都是有目的的。好比我想寫一個爬取美女圖片,咱們就須要對咱們請求到的數據進行一些篩選、匹配,找到對咱們有價值的數據。而這一從網絡請求到數據爬取這整個過程纔是一個完整的爬蟲。有些時候網站的反爬蟲作的比較差,咱們能夠直接在瀏覽器中找到它的API,咱們經過API能夠直接獲取咱們須要的數據,這種相比就要簡單許多。json

3、簡單的爬蟲

簡單的爬蟲就是單純的網絡請求,也能夠對請求的數據進行一些簡單的處理。Python提供了原生的網絡請求模塊urllib,還有封裝版的requests模塊。相比直線requests要更加方便好用,因此本文使用requests進行網絡請求。瀏覽器

3.一、爬取一個簡單的網頁

在咱們發送請求的時候,返回的數據多種多樣,有HTML代碼、json數據、xml數據,還有二進制流。咱們先以百度首頁爲例,進行爬取:bash

import requests# 以get方法發送請求,返回數據response = requests.get('http://www.baidu.com')# 以二進制寫入的方式打開一個文件f = open('index.html', 'wb')# 將響應的字節流寫入文件f.write(response.content)# 關閉文件f.close()

下面咱們看看爬取的網站打開是什麼樣子的:服務器

這就是咱們熟悉的百度頁面,上面看起來仍是比較完整的。咱們再以其它網站爲例,能夠就是不一樣的效果了,咱們以CSDN爲例:

能夠看到頁面的佈局已經徹底亂了,並且也丟失了不少東西。學過前端的都知道,一個網頁是由html頁面還有許多靜態文件構成的,而咱們爬取的時候只是將HTML代碼爬取下來,HTML中連接的靜態資源,像css樣式和圖片文件等都沒有爬取,因此會看到這種很奇怪的頁面。

3.二、爬取網頁中的圖片

首先咱們須要明確一點,在爬取一些簡單的網頁時,咱們爬取圖片或者視頻就是匹配出網頁中包含的url信息,也就是咱們說的網址。而後咱們經過這個具體的url進行圖片的下載,這樣就完成了圖片的爬取。咱們有以下url:https://img-blog.csdnimg.cn/2020051614361339.jpg,咱們將這個圖片url來演示下載圖片的代碼:

import requests# 準備urlurl = 'https://img-blog.csdnimg.cn/2020051614361339.jpg'# 發送get請求response = requests.get(url)# 以二進制寫入的方式打開圖片文件f = open('test.jpg', 'wb')# 將文件流寫入圖片f.write(response.content)# 關閉文件f.close()

能夠看到,代碼和上面網頁爬取是同樣的,只是打開的文件後綴爲jpg。實際上圖片、視頻、音頻這種文件用二進制寫入的方式比較恰當,而對應html代碼這種文本信息,咱們一般直接獲取它的文本,獲取方式爲response.text,在咱們獲取文本後就能夠匹配其中的圖片url了。咱們如下列http://topit.pro爲例:

import reimport requests# 要爬取的網站url = 'http://topit.pro'# 獲取網頁源碼response = requests.get(url)# 匹配源碼中的圖片資源results = re.findall("<img[\\s\\S]+?src=\"(.+?)\"", response.text)# 用於命名的變量name = 0# 遍歷結果for result in results: # 在源碼中分析出圖片資源寫的是絕對路徑,因此完整url是主站+絕對路徑 img_url = url+result # 下載圖片 f = open(str(name) + '.jpg', 'wb') f.write(requests.get(img_url).content) f.close() name += 1

上面咱們就完成了一個網站的爬取。在匹配時咱們用到了正則表達式,由於正則的內容比較多,在這裏就不展開了,有興趣的讀者能夠本身去了解一下,這裏只說一個簡單的。Python使用正則是經過re模塊實現的,能夠調用findall匹配文本中全部符合要求的字符串。該函數傳入兩個參數,第一個爲正則表達式,第二個爲要匹配的字符串,對正則不瞭解的話只須要知道咱們使用該正則能夠將圖片中的src內容拿出來。

4、使用BeautifulSoup解析HTML

BeautifulSoup是一個用來分析XML文件和HTML文件的模塊,咱們前面使用正則表達式進行模式匹配,但本身寫正則表達式是一個比較繁瑣的過程,並且容易出錯。若是咱們把解析工做交給BeautifulSoup會大大減小咱們的工做量,在使用以前咱們先安裝。

4.一、BeautifulSoup的安裝和簡單使用

咱們直接使用pip安裝:

pip install beautifulsoup4

模塊的導入以下:

from bs4 import BeautifulSoup

下面咱們就來看看BeautifulSoup的使用,咱們用下面HTML文件測試:

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <img class="test" src="1.jpg"> <img class="test" src="2.jpg"> <img class="test" src="3.jpg"> <img class="test" src="4.jpg"> <img class="test" src="5.jpg"> <img class="test" src="6.jpg"> <img class="test" src="7.jpg"> <img class="test" src="8.jpg"></body></html>

上面是一個很是簡答的html頁面,body內包含了8個img標籤,如今咱們須要獲取它們的src,代碼以下:

from bs4 import BeautifulSoup
# 讀取html文件f = open('test.html', 'r')str = f.read()f.close()
# 建立BeautifulSoup對象,第一個參數爲解析的字符串,第二個參數爲解析器soup = BeautifulSoup(str, 'html.parser')
# 匹配內容,第一個爲標籤名稱,第二個爲限定屬性,下面表示匹配class爲test的img標籤img_list = soup.find_all('img', {'class':'test'})
# 遍歷標籤 for img in img_list: # 獲取img標籤的src值 src = img['src'] print(src)

解析結果以下:

1.jpg2.jpg3.jpg4.jpg5.jpg6.jpg7.jpg8.jpg

正好就是咱們須要的內容。

4.二、BeautifulSoup實戰

咱們能夠針對網頁進行解析,解析出其中的src,這樣咱們就能夠進行圖片等資源文件的爬取。下面咱們用梨視頻爲例,進行視頻的爬取。主頁網址以下:https://www.pearvideo.com/。咱們右鍵檢查能夠看到以下頁面:咱們能夠先點擊1處,而後選擇須要爬取的位置,好比2,在右邊就會跳轉到相應的位置。咱們能夠看到外層套了一個a標籤,在咱們實際操做是發現點擊2的位置跳轉了網頁,分析出來跳轉的網頁應該就是a標籤中的herf值。由於herf值是以/開頭的,因此完整的URL應該是主站+href值,知道了這個咱們就能夠進行下一步的操做了,咱們先從主站爬取跳轉的url:

import requestsfrom bs4 import BeautifulSoup# 主站url = 'https://www.pearvideo.com/'# 模擬瀏覽器訪問headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}# 發送請求response = requests.get(url, headers=headers)# 獲取BeautifulSoup對象soup = BeautifulSoup(response.text, 'html.parser')# 解析出符合要求的a標籤video_list = soup.find_all('a', {'class':'actwapslide-link'})# 遍歷標籤for video in video_list: # 獲取herf並組拼成完整的url video_url = video['href'] video_url = url + video_url print(video_url)

輸出結果以下:

https://www.pearvideo.com/video_1674906https://www.pearvideo.com/video_1674921https://www.pearvideo.com/video_1674905https://www.pearvideo.com/video_1641829https://www.pearvideo.com/video_1674822

咱們只爬取一個就行了,咱們進入第一個網址查看源碼,發現了這麼一句:

var contId="1674906",liveStatusUrl="liveStatus.jsp",liveSta="",playSta="1",autoPlay=!1,isLiving=!1,isVrVideo=!1,hdflvUrl="",sdflvUrl="",hdUrl="",sdUrl="",ldUrl="",srcUrl="https://video.pearvideo.com/mp4/adshort/20200517/cont-1674906-15146856_adpkg-ad_hd.mp4",vdoUrl=srcUrl,skinRes="//www.pearvideo.com/domain/skin",videoCDN="//video.pearvideo.com";

其中srcUrl就包含了視頻文件的網站,可是咱們確定不能本身一個網頁一個網頁本身找,咱們可使用正則表達式:

import re# 獲取單個視頻網頁的源碼response = requests.get(video_url)# 匹配視頻網址results = re.findall('srcUrl="(.*?)"', response.text)# 輸出結果print(results)

結果以下:

['https://video.pearvideo.com/mp4/adshort/20200516/cont-1674822-14379289-191950_adpkg-ad_hd.mp4']

而後咱們就能夠下載這個視頻了:

with open('result.mp4', 'wb') as f: f.write(requests.get(results[0], headers=headers).content)

完整代碼以下:

import reimport requestsfrom bs4 import BeautifulSoup# 主站url = 'https://www.pearvideo.com/'# 模擬瀏覽器訪問headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}# 發送請求response = requests.get(url, headers=headers)# 獲取BeautifulSoup對象soup = BeautifulSoup(response.text, 'html.parser')# 解析出符合要求的a標籤video_list = soup.find_all('a', {'class':'actwapslide-link'})# 遍歷標籤video_url = video_list[0]['href']
response = requests.get(video_url)
results = re.findall('srcUrl="(.*?)"', response.text)
with open('result.mp4', 'wb') as f: f.write(requests.get(results[0], headers=headers).content)

到此咱們就從簡單的網頁到圖片再到視頻實現了幾個不一樣的爬蟲。


本文分享自微信公衆號 - ZackSock(ZackSock)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索