前言
hello,大家好
本章可是一個重中之重,因為我們今天是要爬取一個圖片而不是一個網頁或是一個json
所以我們也就不用用到selenium模塊了,當然有興趣的同學也一樣可以使用selenium去爬取。
為了方便我們就用requests模塊就夠了,因為夠快。。。
上章的課程傳送門:
[python網絡爬蟲之入門[一]](https://www.cnblogs.com/liwangwang/p/11977110.html)
[python網絡爬蟲之自動化測試工具selenium\[二\]](https://www.cnblogs.com/liwangwang/p/11977134.html)
理一下本章思路:
- 學習並掌握好正則表達式
- 使用正則表達式去分析網站來獲取特定信息
一、正則表達式的學習
1、正則表達式的匹配工具
如果是學過正則表達式的卻不知道這個工具的話,那絕對是一個很大的遺憾。
這個也叫做貓頭鷹,
可能還有一些比較好用的工具把,但這個就已經夠用了,
下載路徑:
鏈接:https://pan.baidu.com/s/1g8Zn-CKopsnCjA_o9jS0TQ
提取碼:iq9s
2、正則表達式的樣式
本着大家好,我好的思想理念,所以我覺得給大家起一個匹配案例就行了,其他的正則自己可以慢慢看代碼理解
放圖:
使用regexbuddy做檢測:
失敗案例
在python中的一個測試
3、正則表達式的案例
""" 正則表達式 """ import re str = "Liwangwang321@163.com" # 匹配所有郵箱 # f = re.match("^\w{4,20}@\w+\.com$",str) # 匹配qq或163郵箱 # f = re.match("\w{4,20}@(qq|163)\.com",str) # 匹配<div><span>python</span></div> \num方法 # str = "<div><span>python</span></div>" # f = re.match("<([A-Za-z]+)><([A-Za-z]+)>.*</\\2></\\1>",str) # 匹配<div><span>python</span></div> 起別名方法 str = "<div><span>python</span></div>" f = re.match("<(?P<name1>[A-Za-z]+)><(?P<name2>[A-Za-z]+)>.*</(?P=name2)></(?P=name1)>",str) # 2、match和search的區別 # str = "你好,123,現在在線人數為9999" # f = re.match("\\d*",str) # f = re.search(",\\d*",str) # f = re.findall("\\d*",str) # 3、貪婪與非貪婪 :加個?就行 # f = re.findall('src=".*"',str) # f = re.findall('src=".*?"',str) # 4、免寫轉義\\ : 加個r # f = re.match(r"<([A-Za-z]+)><([A-Za-z]+)>.*</\2></\1>",str) if f: print("匹配成功") print(f.group()) # for i in f: # print(i) else: print("匹配失敗")
二、爬取網頁圖片
1、分析網頁
我們此次爬取的對象為http://pic.netbian.com/4kdongma
獲取指定的圖片查看:
但是呢,一個展示圖片根本不能符合我們的要求,
所以我們點擊進去看看:
F12檢索網頁代碼;
ok,我們查看一下這個圖片路徑http://pic.netbian.com/uploads/allimg/180222/231102-151931226201f1.jpg
接下來就是去分析一個網頁的結構,確定好用什么正則表達式才能准確的拿到a標簽的href,或者img標簽的src
這個非常重要,重要,重要!!
比如
ok,一步一步的分析網頁結構:
那么接下來的那個點擊進去之后的html路經,我們照樣可以通過這個方法訪問,解析
下面自己測試
import requests import re from fake_useragent import UserAgent ua = UserAgent(verify_ssl=False) headers = { "Cookie": "__cfduid=d475437d729908631eff1e1d69f0314c81574259376; zkhanecookieclassrecord=%2C66%2C; Hm_lvt_526caf4e20c21f06a4e9209712d6a20e=1574259380,1574691901,1574734052; security_session_verify=ebb4b36dc44da23d2cdd02fa4650ae15; Hm_lpvt_526caf4e20c21f06a4e9209712d6a20e=1574735387" , "User-Agent": ua.random } rep = requests.get("http://pic.netbian.com/4kdongman/index.html", headers=headers, verify=False) rep.encoding="gbk" # result = """<a href="(.*?)" target="_blank"><img src=".*?" alt=".*?" /><b>.*?</b></a>""" # 拿一個正則表達式去匹配 # contents = re.findall(result, rep.text) print(rep.text) # for content in contents: # print(content)
2、獲取數據
我們先看一下圖解:
全部代碼
""" 爬取4k動漫圖片 """ import requests import time import os import re from fake_useragent import UserAgent ua = UserAgent(verify_ssl=False) headers = { "Cookie": "__cfduid=d475437d729908631eff1e1d69f0314c81574259376; zkhanecookieclassrecord=%2C66%2C; Hm_lvt_526caf4e20c21f06a4e9209712d6a20e=1574259380,1574691901,1574734052; security_session_verify=645e98edf446fb2efa862d275906b0ba; Hm_lpvt_526caf4e20c21f06a4e9209712d6a20e=1574782670" , "User-Agent": ua.random } # 獲取當前目錄 root = os.getcwd() # range此參數可以自己更改,第幾頁到第幾頁 for page in range(0, 125): # 進入當前目錄 os.chdir(root) # 創建文件夾 os.mkdir(f"4k動漫的第{page+1}頁") # 改變當前文件目錄 os.chdir(f"4k動漫的第{page+1}頁") if page+1 == 1: url = f"http://pic.netbian.com/4kdongman/index.html" else: url = f"http://pic.netbian.com/4kdongman/index_{page + 1}.html" response = requests.get(url,headers=headers,verify=False) response.encoding="gbk" if response.status_code == 200 : result= """<a href="(.*?)" target="_blank"><img src=".*?" alt=".*?" /><b>.*?</b></a>""" # 拿一個正則表達式去匹配 contents = re.findall(result,response.text) # 去遍歷所有的圖片 for content in contents: path = content print(f"{path}正在進入html......") response2 = requests.get("http://pic.netbian.com"+path, headers=headers,verify=False) response2.encoding = "gbk" time.sleep(1) result2 = """<a href="" id="img"><img src="(.*?)" data-pic=".*?" alt="(.*?)" title=".*?"></a>""" contents2 = re.findall(result2, response2.text) for content2 in contents2: path2 = content2[0] name = content2[1] response3 = requests.get("http://pic.netbian.com"+path2, headers=headers,verify=False) # 保存到本地 with open(f"{name}.jpg","wb") as f: f.write(response3.content) print(f"{name} : {path2} 保存成功,等待1秒后繼續爬取") time.sleep(1) print(f"第{page + 1}頁抓取成功,,等待2秒后繼續爬取") time.sleep(2)
爬取妹子網的案例
這個案例來自於:https://blog.csdn.net/qq_33958297/article/details/89388556
爬取的網站:https://www.mzitu.com/
# -*- coding: utf-8 -*- import requests import os from lxml import etree from threading import * from time import sleep nMaxThread = 3 #這里設置需要開啟幾條線程 ThreadLock = BoundedSemaphore(nMaxThread) gHeads = { "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36", } class Meizitu(Thread): def __init__(self,url,title): Thread.__init__(self) self.url = url #這里的url在后面的referer中需要使用 self.title = title def run(self): try: PhotoUrl,Page = self.GetPhotoUrlAndPageNum() if PhotoUrl and Page > 0: self.SavePhoto(PhotoUrl,Page) finally: ThreadLock.release() def GetPhotoUrlAndPageNum(self): html = requests.get(self.url,headers=gHeads) if html.status_code == 200: xmlContent = etree.HTML(html.text) PhotoUrl = xmlContent.xpath("//div[@class='main-image']/p/a/img/@src")[0][:-6] #01.jpg 正好是-6 PageNum = xmlContent.xpath("//div[@class='pagenavi']/a[5]/span/text()")[0] return PhotoUrl,int(PageNum) else: return None,None def SavePhoto(self,url,page): savePath = "./photo/%s" % self.title if not os.path.exists(savePath): os.makedirs(savePath) for i in range(page): heads = { "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36", "Referer": "%s/%d" %(self.url,i+1), "Accept": "image/webp,image/apng,image/*,*/*;q=0.8" } j = 0 while j<5: print (u"Download : %s/%d.jpg" % (self.title, i + 1)) html = requests.get("%s%02d.jpg"%(url,i+1),headers=heads) if html.status_code == 200: with open(savePath + "/%d.jpg"%(i+1),"wb") as f: f.write(html.content) break elif html.status_code == 404: j+=1 sleep(0.05) continue else: return None def main(): while True: try: nNum = int(raw_input(u"請輸入要下載幾頁: ")) if nNum>0: break except ValueError: print(u"請輸入數字。") continue for i in range(nNum): url = "https://www.mzitu.com/xinggan/page/%d/"%(i+1) html = requests.get(url,headers=gHeads) if html.status_code == 200: xmlContent = etree.HTML(html.content) hrefList = xmlContent.xpath("//ul[@id='pins']/li/a/@href") titleList = xmlContent.xpath("//ul[@id='pins']/li/a/img/@alt") for i in range(len(hrefList)): ThreadLock.acquire() t = Meizitu(hrefList[i],titleList[i]) t.start() if __name__ == '__main__': main()
后記
如果有正則基礎的可以直接看如何爬取,沒有的可以學一學。
不過regexbuddy工具都可以玩玩看
如果感覺本章寫的還不錯的話,不如。。。。。(~ ̄▽ ̄)~ ,(´▽`ʃ♡ƪ)