Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

其實不少編程語言均可以作爬蟲,例如java、c#、php等等甚至excel均可以抓網頁的圖表,那麼爲何咱們要用Python呢?它簡單、便捷,並且有好多庫能夠選擇,能夠說python是寫爬蟲的首選了!php

今天就來帶你們寫一個簡單而又完整的爬蟲,咱們來抓取整站的圖片的,而且保存到電腦上!html

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

準備工做

工具:Python3.六、pycharmjava

庫:requests、re、time、random、ospython

目標網站:妹子圖(具體url你們本身去代碼裏看。。。)正則表達式

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

在寫代碼以前

在咱們開始寫代碼以前,要先對網站進行分析,重點有這個幾個地方:編程

一、先判斷網頁是否靜態網頁,這個關係咱們採用的爬蟲手段!c#

簡單的說,網頁中的內容,在網頁源代碼中均可以找到,那麼就能夠判定,這個網站是靜態的了;若是沒有找到,就須要去開發者工具中查找,看看是抓包呢仍是分析js結構或者其餘的方式。瀏覽器

二、看看網頁的結構,大體清楚抓取目標數據,須要幾層循環,每次循環的方式,以及是否保證沒有遺漏!服務器

三、根據網頁源代碼來決定採用的匹配方式app

通常來講,正則表達式是處理字符串最快的方式,可是在爬蟲中它的效率並非很高,由於它須要遍歷整個html來匹配相關內容,若是網頁源代碼比較規整的話,建議採用bs4或者xpath等等解析網頁結構的方式比較好!

固然,今天咱們是基礎向的爬蟲,就用正則表達式了,畢竟正則是必須掌握的內容!

那麼,具體怎麼寫爬蟲代碼呢~?簡單的舉例給你們說下:

若是是手工操做的話,大概是這個流程

打開主頁==>選擇一個分類==>選擇一個圖集==>依次選擇圖片==>右鍵保存==>重複以上保存其餘圖片

那麼這個過程放到代碼中呢,它的結構大概是這樣:

訪問主頁url==>找到並循環全部分類==>建立分類文件夾==>訪問分類url==>找到頁碼構建循環分類全部頁==>循環頁面全部圖集==>建立圖集文件夾==>找到圖集內全部圖片url==>保存到對應文件夾

好了,思路也有了,那就廢話很少說了,咱們來寫代碼吧~!

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

開始寫代碼

首先是導入上述的各類庫,沒有的須要安裝一下!而後寫入如下幾行代碼獲取網頁源代碼看看是否有反爬:

import requests
import time
import random
import re
import os


url = 'http://www.meizitu.com/'
html = requests.get(url)
html.encoding = 'gb2312'

若是能順利打印出源代碼且和網頁右鍵查看的源代碼一致,那麼能夠斷定該網站基本沒有反爬了!

第16行代碼的含義是給html設定編碼格式。由於Python3默認是utf-8,若是網站不是這個編碼格式的話,會出現亂碼,因此咱們直接指定一下。

接下來呢,就是找到全部分類的名字和url了,來看看網頁中和源代碼中,它的位置在哪

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

所有在a標籤的屬性中,那麼咱們能夠用一行代碼獲取了

infos = re.findall(r'a href="(http://www.meizitu.com/.*?html)" target="_blank" title="(.*?)" ',html.text)

這裏用正則匹配,2個括號中的內容就是咱們須要的url和名字了,而後開始構建循環遍歷全部的分類

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

上一步取出的infos是列表,並且每個元素都是一個元組,格式爲(url,名字),全部咱們用2個元素去遍歷infos,來獲取咱們須要的內容,先打印下看看結果是否正確!

這裏先不建立文件夾,先進行下一步,訪問分類的url,而後開始構建分類中的頁碼吧!分析網頁發現,全部的頁碼都在下方,可是仍是稍有不一樣:沒有當前頁、多了下一頁和末頁

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

因爲存在圖集不足一頁的狀況(上述源代碼就不會出現),因此咱們這麼處理循環

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

19-21行獲取分類的源代碼,22行獲取全部頁碼的url,而後用set()函數去重,再新建一個空列表,將分類的url加進去,注意,元組是不能用append()方法添加到列表中的,因此要先將set元組轉化爲列表而後分別從新拼接列表內全部的url,在將2個列表相加的方式合併爲一個列表!這樣咱們就獲得了分類下全部翻頁頁面的url

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

循環全部的url,獲取全部圖集的url列表,27行沒有用encoding指定編碼是由於這裏我不須要取到中文的內容,因此簡寫了一下!終於該取圖片了!

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

圖集的title和圖集內全部圖片的url都取到了!其實到這裏就已經完成了爬蟲的80%了!剩下的20%就是保存圖片到本地,這裏就很少說了,給你們提供2個代碼片斷,一個是新建文件夾並判斷是否存在,一個是剔除字符串內不符合命名要求的字符

path = 'E://python/mn/meizitu/%s/'%sor#路徑
if os.path.exists(path):#判斷路徑及文件夾是否存在,不存在即建立
	pass
else:
	os.mkdir(path)
def new_title(title):
	rstr = r"[\/\\\:\*\?\"\<\>\|]"  # '/ \ : * ? " < > |'
	new_title = re.sub(rstr, "_", title)  # 替換爲下劃線
	return new_title

最終完整代碼和運行效果

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

在請求中加入了時間模塊的暫停功能,不加入的話可能會被網頁拒絕訪問!

在最後請求圖片地址的時候,須要加入UA來告訴服務器你是瀏覽器而不是腳本,這個是最經常使用的反爬手段了

#author:雲飛
#QQ羣542110741
import requests
import time
import random
import re
import os

def new_title(title):
	rstr = r"[\/\\\:\*\?\"\<\>\|]"  # '/ \ : * ? " < > |'
	new_title = re.sub(rstr, "_", title)  # 替換爲下劃線
	return new_title

url = 'http://www.meizitu.com/'
html = requests.get(url)
html.encoding = 'gb2312'
infos = re.findall(r'a href="(http://www.meizitu.com/.*?html)"  target="_blank" title="(.*?)" ',html.text)
i = 1
for sor_url,sor in infos:
	sor = new_title(sor)
	path = 'E://python/mn/meizitu/%s/'%sor#路徑
	if os.path.exists(path):#判斷路徑及文件夾是否存在,不存在即建立
		pass
	else:
		os.mkdir(path)
	time.sleep(random.random())
	sor_html = requests.get(sor_url)
	sor_html.encoding = 'gb2312'
	atlas = set(re.findall(r"<li><a href='(.*?html)'>\d+</a></li>",sor_html.text))
	atlas_lis = []
	atlas_lis.append(sor_url)
	atlas_lis += [url+'a/'+x for x in list(atlas)]
	for atla in atlas_lis:
		atla_html = requests.get(atla).text
		at_url_lis = re.findall(r'h3 class="tit"><a href="(http://www.meizitu.com/.*?html)"  targe',atla_html)
		for at_url in at_url_lis:
			at_html = requests.get(at_url)
			at_html.encoding = "gb2312"
			atlas_title = ''.join(re.findall(r'<title>(.*?)</title>',at_html.text))
			atlas_title = new_title(atlas_title)
			img_path = 'E://python/mn/meizitu/%s/%s/'%(sor,atlas_title)
			if os.path.exists(img_path):#判斷路徑及文件夾是否存在,不存在即建立
				pass
			else:
				os.mkdir(img_path)
			img_urls = re.findall(r'src="(http://mm.chinasareview.com/.*?jpg)" /><br />',at_html.text)
			k = 1
			for img_url in img_urls:
				header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:57.0) Gecko/20100101 Firefox/57.0'}
				data = requests.get(img_url,headers=header).content#獲取圖片的二進制格式
				with open('%s%s'%(img_path,img_url.split('/')[-1]),'wb') as f:
					f.write(data)
				print("【正在下載】 {%s}的第%d張圖片,一共下載了%d張圖片"%(atlas_title,k,i))
				i += 1
				k += 1

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

下載一段時間後的效果

Python老司機手把手帶你寫爬蟲,整站下載妹子圖,一次爽個夠!

相關文章
相關標籤/搜索